import_dae.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 * VCGLib                                                            o o     *
00003 * Visual and Computer Graphics Library                            o     o   *
00004 *                                                                _   O  _   *
00005 * Copyright(C) 2004-2008                                           \/)\/    *
00006 * Visual Computing Lab                                            /\/|      *
00007 * ISTI - Italian National Research Council                           |      *
00008 *                                                                    \      *
00009 * All rights reserved.                                                      *
00010 *                                                                           *
00011 * This program is free software; you can redistribute it and/or modify      *
00012 * it under the terms of the GNU General Public License as published by      *
00013 * the Free Software Foundation; either version 2 of the License, or         *
00014 * (at your option) any later version.                                       *
00015 *                                                                           *
00016 * This program is distributed in the hope that it will be useful,           *
00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
00019 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
00020 * for more details.                                                         *
00021 *                                                                           *
00022 ****************************************************************************/
00023 
00024 #ifndef __VCGLIB_IMPORTERDAE
00025 #define __VCGLIB_IMPORTERDAE
00026 
00027 //importer for collada's files
00028 
00029 #include <wrap/dae/util_dae.h>
00030 #include <wrap/dae/poly_triangulator.h>
00031 
00032 // uncomment one of the following line to enable the Verbose debugging for the parsing
00033 //#define QDEBUG if(1) ; else {assert(0);}
00034 #define QDEBUG qDebug
00035 
00036 namespace vcg {
00037 namespace tri {
00038 namespace io {
00039     template<typename OpenMeshType>
00040     class ImporterDAE : public UtilDAE
00041     {
00042   public:
00043     class ColladaFace;
00044     class ColladaVertex;
00045 
00046     class ColladaTypes: public vcg::UsedTypes < vcg::Use<ColladaVertex>::template AsVertexType,
00047                                                                                                 vcg::Use<ColladaFace  >::template AsFaceType >{};
00048 
00049     class ColladaVertex  : public vcg::Vertex< ColladaTypes,
00050       vcg::vertex::Coord3f,           /* 12b */
00051       vcg::vertex::BitFlags,          /*  4b */
00052       vcg::vertex::Normal3f,          /* 12b */
00053       vcg::vertex::Color4b           /*  4b */
00054       > {};
00055 
00056 
00057     class ColladaFace    : public vcg::Face<  ColladaTypes,
00058           vcg::face::VertexRef,            /*12b */
00059           vcg::face::BitFlags,             /* 4b */
00060           vcg::face::Normal3f,             /*12b */
00061           vcg::face::Color4b,           /* 0b */
00062           vcg::face::WedgeTexCoord2f     /* 0b */
00063         > {};
00064 
00065     class ColladaMesh    : public vcg::tri::TriMesh< std::vector<ColladaVertex>, std::vector<ColladaFace> > {};
00066 
00067 
00068 
00069     private:
00070 
00071 
00072 
00073 
00074 
00075 
00076         static int WedgeNormalAttribute(ColladaMesh& m,const QStringList face,const QStringList wn,const QDomNode wnsrc,const int meshfaceind,const int faceind,const int component)
00077         {
00078             int indnm = -1;
00079             if (!wnsrc.isNull())
00080             {
00081                 indnm = face.at(faceind).toInt();
00082                 assert(indnm * 3 < wn.size());
00083                 m.face[meshfaceind].WN(component) = vcg::Point3f(wn.at(indnm * 3).toFloat(),wn.at(indnm * 3 + 1).toFloat(),wn.at(indnm * 3 + 2).toFloat());
00084             }
00085             return indnm;
00086         }
00087 
00088         static int WedgeTextureAttribute(ColladaMesh& 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)
00089         {
00090             int indtx = -1;
00091             if (!wtsrc.isNull())
00092             {
00093                 indtx = face.at(faceind).toInt();
00094                 //int num = wt.size();
00095                 assert(indtx * stride < wt.size());
00096                 m.face[meshfaceind].WT(component) = vcg::TexCoord2<float>();
00097                 m.face[meshfaceind].WT(component).U() = wt.at(indtx * stride).toFloat();
00098                 m.face[meshfaceind].WT(component).V() = wt.at(indtx * stride + 1).toFloat();
00099 
00100                 m.face[meshfaceind].WT(component).N() = ind_txt;
00101 
00102             }
00103             return indtx;
00104         }
00105 
00106         // this one is used for the polylist nodes
00107         static int WedgeTextureAttribute(typename ColladaMesh::FaceType::TexCoordType & WT, const QStringList faceIndexList, int ind_txt, const QStringList wt, const QDomNode wtsrc,const int faceind,const int stride = 2)
00108         {
00109             int indtx = -1;
00110             if (!wtsrc.isNull())
00111             {
00112                 indtx = faceIndexList.at(faceind).toInt();
00113                 //int num = wt.size();
00114                 assert(indtx * stride < wt.size());
00115                 WT = vcg::TexCoord2<float>();
00116                 WT.U() = wt.at(indtx * stride).toFloat();
00117                 WT.V() = wt.at(indtx * stride + 1).toFloat();
00118                 WT.N() = ind_txt;
00119             }
00120             return indtx;
00121         }
00122 
00123         static int VertexColorAttribute(ColladaMesh& m,const QStringList face,const QStringList wc,const QDomNode wcsrc,const int faceind, const int vertind,const int colorcomponent)
00124         {
00125             int indcl = -1;
00126             if (!wcsrc.isNull())
00127             {
00128                 indcl = face.at(faceind).toInt();
00129                 assert((colorcomponent == 4) || (colorcomponent == 3));
00130                 assert(indcl * colorcomponent < wc.size());
00131                 vcg::Color4b c;
00132                 if (colorcomponent == 3)
00133                     c[3] = 255;
00134                 for(unsigned int ii = 0;ii < colorcomponent;++ii)
00135                     c[ii] = (unsigned char)(wc.at(indcl * colorcomponent + ii).toFloat()*255.0);
00136                 m.vert[vertind].C() = c;
00137             }
00138             return indcl;
00139         }
00140 
00141 
00142         static void FindStandardWedgeAttributes(WedgeAttribute& wed,const QDomNode nd,const QDomDocument doc)
00143         {
00144             wed.wnsrc = findNodeBySpecificAttributeValue(nd,"input","semantic","NORMAL");
00145             wed.offnm = findStringListAttribute(wed.wn,wed.wnsrc,nd,doc,"NORMAL");
00146 
00147             wed.wtsrc = findNodeBySpecificAttributeValue(nd,"input","semantic","TEXCOORD");
00148             if (!wed.wtsrc.isNull())
00149             {
00150                 QDomNode src = attributeSourcePerSimplex(nd,doc,"TEXCOORD");
00151                 if (isThereTag(src,"accessor"))
00152                 {
00153                     QDomNodeList wedatts = src.toElement().elementsByTagName("accessor");
00154                     wed.stridetx = wedatts.at(0).toElement().attribute("stride").toInt();
00155                 }
00156                 else
00157                     wed.stridetx = 2;
00158             }
00159             //else
00160             //  wed.stridetx = 2;
00161 
00162             wed.offtx = findStringListAttribute(wed.wt,wed.wtsrc,nd,doc,"TEXCOORD");
00163 
00164             wed.wcsrc = findNodeBySpecificAttributeValue(nd,"input","semantic","COLOR");
00165             if (!wed.wcsrc.isNull())
00166             {
00167                 QDomNode src = attributeSourcePerSimplex(nd,doc,"COLOR");
00168                 if (isThereTag(src,"accessor"))
00169                 {
00170                     QDomNodeList wedatts = src.toElement().elementsByTagName("accessor");
00171                     wed.stridecl = wedatts.at(0).toElement().attribute("stride").toInt();
00172                 }
00173                 else
00174                     wed.stridecl = 3;
00175             }
00176             /*else
00177                 wed.stridecl = 3;*/
00178             wed.offcl = findStringListAttribute(wed.wc,wed.wcsrc,nd,doc,"COLOR");
00179         }
00180 
00181         static DAEError LoadPolygonalMesh(QDomNodeList& polypatch,ColladaMesh& m,const size_t offset,InfoDAE & info)
00182         {
00183             return E_NOERROR;
00184         }
00185 
00186         static DAEError LoadPolygonalListMesh(QDomNodeList& polylist,ColladaMesh& m,const size_t offset,InfoDAE& info,QMap<QString,QString> &materialBinding)
00187         {
00188             if(polylist.isEmpty()) return E_NOERROR;
00189             QDEBUG("****** LoadPolygonalListMesh (initial mesh size %i %i)",m.vert.size(),m.fn);
00190             for(int tript = 0; tript < polylist.size();++tript)
00191             {
00192                 QString materialId =  polylist.at(tript).toElement().attribute(QString("material"));
00193                 QDEBUG("******    material id '%s' -> '%s'",qPrintable(materialId),qPrintable(materialBinding[materialId]));
00194 
00195                 QString textureFilename;
00196                 QDomNode img_node = textureFinder(materialBinding[materialId],textureFilename,*(info.doc));
00197                 if(img_node.isNull())
00198                 {
00199                     QDEBUG("******   but we were not able to find the corresponding image node");
00200                 }
00201 
00202                 int ind_txt = -1;
00203                 if (!img_node.isNull())
00204                 {
00205                     if(info.textureIdMap.contains(textureFilename))
00206                          ind_txt=info.textureIdMap[textureFilename];
00207                     else
00208                     {
00209                         QDEBUG("Found use of Texture %s, adding it to texutres",qPrintable(textureFilename));
00210                         // Note that sometimes (in collada) the texture names could have been encoded with a url-like style (e.g. replacing spaces with '%20') so making some other attempt could be harmless
00211                         QString ConvertedName = textureFilename.replace(QString("%20"), QString(" "));
00212 
00213                         info.textureIdMap[textureFilename]=m.textures.size();
00214                         m.textures.push_back(qPrintable(ConvertedName));
00215                         ind_txt=info.textureIdMap[textureFilename];
00216                     }
00217                 }
00218                 // number of the attributes associated to each vertex of a face (vert, normal, tex etc)
00219                 int faceAttributeNum = polylist.at(tript).toElement().elementsByTagName("input").size();
00220 
00221                 // the list of indexes composing the size of each polygon.
00222                 // The size of this list is the number of the polygons.
00223                 QStringList faceSizeList;
00224                 valueStringList(faceSizeList,polylist.at(tript),"vcount");
00225 
00226                 // The long list of indexes composing the various polygons.
00227                 // for each polygon there are numvert*numattrib indexes.
00228                 QStringList faceIndexList;
00229                 valueStringList(faceIndexList,polylist.at(tript),"p");
00230 
00231                 //int offsetface = (int)m.face.size();
00232                 if (faceIndexList.size() != 0 && faceSizeList.size() != 0 )
00233                 {
00234                     WedgeAttribute wa;
00235                     FindStandardWedgeAttributes(wa,polylist.at(tript),*(info.doc));
00236                     QDEBUG("*******                 Start Reading faces. Attributes Offsets: offtx %i - offnm %i - offcl %i",wa.offtx,wa.offnm,wa.offcl);
00237 
00238           int faceIndexCnt=0;
00239                     int jj = 0;
00240                     for(int ff = 0; ff < (int) faceSizeList.size();++ff) // for each polygon
00241                     {
00242                         int curFaceVertNum = faceSizeList.at(ff).toInt();
00243 
00244                         MyPolygon<typename ColladaMesh::VertexType>  polyTemp(curFaceVertNum);
00245                         for(int tt = 0;tt < curFaceVertNum ;++tt)  // for each vertex of the polygon
00246                         {
00247                             int indvt = faceIndexList.at(faceIndexCnt).toInt();
00248                             if(faceSizeList.size()<100) QDEBUG("*******                 Reading face[%3i].V(%i) = %4i  (%i-th of the index list) (face has %i vertices)",ff,tt,indvt,faceIndexCnt,curFaceVertNum);
00249                             assert(indvt + offset < m.vert.size());
00250                             polyTemp._pv[tt] = &(m.vert[indvt + offset]);
00251                             faceIndexCnt +=faceAttributeNum;
00252 
00253                             WedgeTextureAttribute(polyTemp._txc[tt],faceIndexList,ind_txt, wa.wt ,wa.wtsrc, jj + wa.offtx,wa.stridetx);
00254 
00255                             /****************
00256 
00257                             if(tri::HasPerWedgeNormal(m)) WedgeNormalAttribute(m,face,wa.wn,wa.wnsrc,ff,jj + wa.offnm,tt);
00258                             if(tri::HasPerWedgeColor(m))        WedgeColorAttribute(m,face,wa.wc,wa.wcsrc,ff,jj + wa.offcl,tt);
00259 
00260                             if(tri::HasPerWedgeTexCoord(m) && ind_txt != -1)
00261                             {
00262                                                             WedgeTextureAttribute(m,face,ind_txt,wa.wt,wa.wtsrc,ff,jj + wa.offtx,tt,wa.stride);
00263                             }
00264                                     ****************/
00265 
00266                             jj += faceAttributeNum;
00267                         }
00268 
00269                         AddPolygonToMesh(polyTemp,m);
00270                     }
00271                 }
00272 
00273             }
00274             QDEBUG("****** LoadPolygonalListMesh (final  mesh size vn %i vertsize %i - fn %i facesize %i)",m.vn,m.vert.size(),m.fn,m.face.size());
00275             return E_NOERROR;
00276         }
00277 
00278     static DAEError AddPolygonToMesh(MyPolygon<typename ColladaMesh::VertexType>  &polyTemp, ColladaMesh& m)
00279         {
00280             int vertNum=polyTemp._pv.size();
00281             int triNum= vertNum -2;
00282             typename ColladaMesh::FaceIterator fp=vcg::tri::Allocator<ColladaMesh>::AddFaces(m,triNum);
00283             // Very simple fan triangulation of the polygon.
00284             for(int i=0;i<triNum;++i)
00285             {
00286                 assert(fp!=m.face.end());
00287                 (*fp).V(0)=polyTemp._pv[0];
00288                 (*fp).WT(0)=polyTemp._txc[0];
00289 
00290                 (*fp).V(1) =polyTemp._pv [i+1];
00291                 (*fp).WT(1)=polyTemp._txc[i+1];
00292 
00293                 (*fp).V(2) =polyTemp._pv[i+2];
00294                 (*fp).WT(2)=polyTemp._txc[i+2];
00295 
00296                 ++fp;
00297             }
00298             assert(fp==m.face.end());
00299             return E_NOERROR;
00300         }
00301 
00302         static DAEError OldLoadPolygonalListMesh(QDomNodeList& polylist,ColladaMesh& m,const size_t offset,InfoDAE& info)
00303         {
00304             typedef PolygonalMesh< MyPolygon<typename ColladaMesh::VertexType> > PolyMesh;
00305             PolyMesh pm;
00306 
00307             //copying vertices
00308             for(typename ColladaMesh::VertexIterator itv = m.vert.begin();itv != m.vert.end();++itv)
00309             {
00310                 vcg::Point3f p(itv->P().X(),itv->P().Y(),itv->P().Z());
00311                 typename PolyMesh::VertexType v;
00312                 v.P() = p;
00313                 pm.vert.push_back(v);
00314             }
00315 
00316             int polylist_size = polylist.size();
00317             for(int pl = 0; pl < polylist_size;++pl)
00318             {
00319                 QString mat =  polylist.at(pl).toElement().attribute(QString("material"));
00320                 QString textureFilename;
00321                 QDomNode txt_node = textureFinder(mat,textureFilename,*(info.doc));
00322                 int ind_txt = -1;
00323                 if (!txt_node.isNull())
00324                     ind_txt = indexTextureByImgNode(*(info.doc),txt_node);
00325 
00326                 //PolyMesh::PERWEDGEATTRIBUTETYPE att = PolyMesh::NONE;
00327                 WedgeAttribute wa;
00328                 FindStandardWedgeAttributes(wa,polylist.at(pl),*(info.doc));
00329                 QStringList vertcount;
00330                 valueStringList(vertcount,polylist.at(pl),"vcount");
00331                 int indforpol = findOffSetForASingleSimplex(polylist.at(pl));
00332                 int offpols = 0;
00333                 int npolig = vertcount.size();
00334                 QStringList polyind;
00335                 valueStringList(polyind,polylist.at(pl),"p");
00336                 for(int ii = 0;ii < npolig;++ii)
00337                 {
00338                     int nvert = vertcount.at(ii).toInt();
00339                     typename PolyMesh::FaceType p(nvert);
00340 
00341                     for(int iv = 0;iv < nvert;++iv)
00342                     {
00343                         int index = offset + polyind.at(offpols + iv * indforpol).toInt();
00344                         p._pv[iv] = &(pm.vert[index]);
00345                         int nmindex = -1;
00346 
00347                         if (!wa.wnsrc.isNull())
00348                             nmindex = offset + polyind.at(offpols + iv * indforpol + wa.offnm).toInt();
00349 
00350                         int txindex = -1;
00351                         if (!wa.wtsrc.isNull())
00352                         {
00353                             txindex = offset + polyind.at(offpols + iv * indforpol + wa.offtx).toInt();
00354                             /*p._txc[iv].U() = wa.wt.at(txindex * 2).toFloat();
00355                             p._txc[iv].V() = wa.wt.at(txindex * 2 + 1).toFloat();
00356                             p._txc[iv].N() = ind_txt;*/
00357                         }
00358                     }
00359                     pm._pols.push_back(p);
00360                     offpols += nvert * indforpol;
00361                 }
00362             }
00363             pm.triangulate(m);
00364             return E_NOERROR;
00365         }
00366         /*
00367          Called to load into a given mesh
00368          */
00369         static DAEError LoadTriangularMesh(QDomNodeList& triNodeList, ColladaMesh& m, const size_t offset, InfoDAE& info,QMap<QString,QString> &materialBinding)
00370         {
00371             if(triNodeList.isEmpty()) return E_NOERROR;
00372             QDEBUG("****** LoadTriangularMesh (initial mesh size %i %i)",m.vn,m.fn);
00373             for(int tript = 0; tript < triNodeList.size();++tript)
00374             {
00375                 QString materialId =  triNodeList.at(tript).toElement().attribute(QString("material"));
00376                 QDEBUG("******    material id '%s' -> '%s'",qPrintable(materialId),qPrintable(materialBinding[materialId]));
00377 
00378                 QString textureFilename;
00379                 QDomNode img_node = textureFinder(materialBinding[materialId],textureFilename,*(info.doc));
00380                 if(img_node.isNull())
00381                 {
00382                     QDEBUG("******   but we were not able to find the corresponding image node");
00383                 }
00384 
00385                 int ind_txt = -1;
00386                 if (!img_node.isNull())
00387                 {
00388                     if(info.textureIdMap.contains(textureFilename))
00389                          ind_txt=info.textureIdMap[textureFilename];
00390                     else
00391                     {
00392                         QDEBUG("Found use of Texture %s, adding it to texutres",qPrintable(textureFilename));
00393                         QString ConvertedName = textureFilename.replace(QString("%20"), QString(" "));
00394                         info.textureIdMap[textureFilename]=m.textures.size();
00395                         m.textures.push_back(qPrintable(ConvertedName));
00396                         ind_txt=info.textureIdMap[textureFilename];
00397                     }
00398                 //      ind_txt = indexTextureByImgNode(*(info.doc),txt_node);
00399                 }
00400                 int faceAttributeNum = triNodeList.at(tript).toElement().elementsByTagName("input").size();
00401 
00402                 QStringList face;
00403                 valueStringList(face,triNodeList.at(tript),"p");
00404                 int offsetface = (int)m.face.size();
00405                 if (face.size() != 0)
00406                 {
00407                     vcg::tri::Allocator<ColladaMesh>::AddFaces(m,face.size() / (faceAttributeNum * 3));
00408                     WedgeAttribute wa;
00409                     FindStandardWedgeAttributes(wa,triNodeList.at(tript),*(info.doc));
00410 
00411                     int jj = 0;
00412                     for(int ff = offsetface;ff < (int) m.face.size();++ff)
00413                     {
00414 
00415                         for(unsigned int tt = 0;tt < 3;++tt)
00416                         {
00417                             int indvt = face.at(jj).toInt();
00418                             assert(indvt + offset < m.vert.size());
00419                             m.face[ff].V(tt) = &(m.vert[indvt + offset]);
00420 
00421                             if(tri::HasPerWedgeNormal(m))
00422                                 WedgeNormalAttribute(m,face,wa.wn,wa.wnsrc,ff,jj + wa.offnm,tt);
00423                             if(tri::HasPerVertexColor(m))
00424                             {
00425                                 VertexColorAttribute(m,face,wa.wc,wa.wcsrc,jj + wa.offcl,indvt + offset,wa.stridecl);
00426                             }
00427 
00428                             if(tri::HasPerWedgeTexCoord(m) && ind_txt != -1)
00429                             {
00430                                 WedgeTextureAttribute(m,face,ind_txt,wa.wt,wa.wtsrc,ff,jj + wa.offtx,tt,wa.stridetx);
00431                             }
00432 
00433                             jj += faceAttributeNum;
00434                         }
00435                         if( ! ( (m.face[ff].V(0) != m.face[ff].V(1)) &&
00436                                         (m.face[ff].V(0) != m.face[ff].V(2)) &&
00437                                         (m.face[ff].V(1) != m.face[ff].V(2)) )  )
00438                                         QDEBUG("********* WARNING face %i, (%i %i %i) is a DEGENERATE FACE!",ff, m.face[ff].V(0) - &m.vert.front(), m.face[ff].V(1) - &m.vert.front(), m.face[ff].V(2) - &m.vert.front());
00439 
00440                     }
00441                 }
00442             }
00443             QDEBUG("****** LoadTriangularMesh (final  mesh size %i %i - %i %i)",m.vn,m.vert.size(),m.fn,m.face.size());
00444             return E_NOERROR;
00445         }
00446 
00447         static int LoadControllerMesh(ColladaMesh& m, InfoDAE& info, const QDomElement& geo,QMap<QString, QString> materialBindingMap, CallBackPos *cb=0)
00448         {
00449             (void)cb;
00450 
00451             assert(geo.tagName() == "controller");
00452             QDomNodeList skinList = geo.toElement().elementsByTagName("skin");
00453             if(skinList.size()!=1) return E_CANTOPEN;
00454             QDomElement skinNode = skinList.at(0).toElement();
00455 
00456             QString geomNode_url;
00457             referenceToANodeAttribute(skinNode,"source",geomNode_url);
00458             QDEBUG("Found a controller referencing a skin with url '%s'", qPrintable(geomNode_url));
00459             QDomNode refNode = findNodeBySpecificAttributeValue(*(info.doc),"geometry","id",geomNode_url);
00460 
00461             QDomNodeList bindingNodes = skinNode.toElement().elementsByTagName("bind_material");
00462             if( bindingNodes.size()>0) {
00463                 QDEBUG("**   skin node of a controller has a material binding");
00464                 GenerateMaterialBinding(skinNode,materialBindingMap);
00465             }
00466             return LoadGeometry(m, info, refNode.toElement(),materialBindingMap);
00467         }
00468 
00469         /* before instancing a geometry you can make a binding that allow you to substitute next material names with other names.
00470         this is very useful for instancing the same geometry with different materials. therefore when you encounter a material name in a mesh, this name can be a 'symbol' that you have to bind.
00471         */
00472         static bool GenerateMaterialBinding(QDomNode instanceGeomNode, QMap<QString,QString> &binding)
00473         {
00474             QDomNodeList instanceMaterialList=instanceGeomNode.toElement().elementsByTagName("instance_material");
00475             QDEBUG("++++ Found %i instance_material binding",instanceMaterialList.size() );
00476             for(int i=0;i<instanceMaterialList.size();++i)
00477             {
00478                 QString symbol = instanceMaterialList.at(i).toElement().attribute("symbol");
00479                 QString target = instanceMaterialList.at(i).toElement().attribute("target");
00480                 binding[symbol]=target;
00481                 QDEBUG("++++++ %s -> %s",qPrintable(symbol),qPrintable(target));
00482             }
00483             return true;
00484         }
00485 
00486 
00487     /*
00488          Basic function that get in input a node <geometry> with a map from material names to texture names.
00489          this map is necessary because when using a geometry when it is instanced its material can be bind with different names.
00490          if the map fails you should directly search in the material library.
00491 
00492          */
00493 
00494         static int LoadGeometry(ColladaMesh& m, InfoDAE& info, const QDomElement& geo, QMap<QString,QString> &materialBinding, CallBackPos *cb=0)
00495         {
00496             assert(geo.tagName() == "geometry");
00497             if (!isThereTag(geo,"mesh")) return E_NOMESH;
00498 
00499             if ((cb !=NULL) && (((info.numvert + info.numface)%100)==0) && !(*cb)((100*(info.numvert + info.numface))/(info.numvert + info.numface), "Vertex Loading"))
00500                     return E_CANTOPEN;
00501             QDEBUG("**** Loading a Geometry Mesh **** (initial mesh size %i %i)",m.vn,m.fn);
00502             QDomNodeList vertices = geo.toElement().elementsByTagName("vertices");
00503             if (vertices.size() != 1) return E_INCOMPATIBLECOLLADA141FORMAT;
00504             QDomElement vertNode = vertices.at(0).toElement();
00505 
00506             QDomNode positionNode = attributeSourcePerSimplex(vertNode,*(info.doc),"POSITION");
00507             if (positionNode.isNull()) return E_NOVERTEXPOSITION;
00508 
00509             QStringList geosrcposarr;
00510             valueStringList(geosrcposarr, positionNode, "float_array");
00511 
00512             int geosrcposarr_size = geosrcposarr.size();
00513             if ((geosrcposarr_size % 3) != 0)
00514                 return E_CANTOPEN;
00515             int nvert = geosrcposarr_size / 3;
00516             size_t offset = m.vert.size();
00517             if (geosrcposarr_size != 0)
00518             {
00519                     vcg::tri::Allocator<ColladaMesh>::AddVertices(m,nvert);
00520 
00521                     QDomNode srcnodenorm = attributeSourcePerSimplex(vertices.at(0),*(info.doc),"NORMAL");
00522                     QStringList geosrcvertnorm;
00523                     if (!srcnodenorm.isNull())
00524                         valueStringList(geosrcvertnorm,srcnodenorm,"float_array");
00525 
00526                     QDomNode srcnodetext = attributeSourcePerSimplex(vertices.at(0),*(info.doc),"TEXCOORD");
00527                     QStringList geosrcverttext;
00528                     if (!srcnodetext.isNull())
00529                         valueStringList(geosrcverttext,srcnodetext,"float_array");
00530 
00531                     QDomNode srcnodecolor = attributeSourcePerSimplex(vertices.at(0),*(info.doc),"COLOR");
00532                     QDomNodeList accesslist = srcnodecolor.toElement().elementsByTagName("accessor");
00533 
00534                     QStringList geosrcvertcol;
00535                     if (!srcnodecolor.isNull())
00536                         valueStringList(geosrcvertcol,srcnodecolor,"float_array");
00537 
00538                     int ii = 0;
00539                     for(size_t vv = offset;vv < m.vert.size();++vv)
00540                     {
00541                         Point3f positionCoord(geosrcposarr[ii * 3].toFloat(),geosrcposarr[ii * 3 + 1].toFloat(),geosrcposarr[ii * 3 + 2].toFloat());
00542                         m.vert[vv].P() = positionCoord;
00543 
00544                         if (!srcnodenorm.isNull())
00545                         {
00546                             Point3f normalCoord(geosrcvertnorm[ii * 3].toFloat(),
00547                                                                     geosrcvertnorm[ii * 3 + 1].toFloat(),
00548                                                                     geosrcvertnorm[ii * 3 + 2].toFloat());
00549                             normalCoord.Normalize();
00550                             m.vert[vv].N() = normalCoord;
00551                         }
00552 
00553                         if (!srcnodecolor.isNull())
00554                         {
00555                             if (accesslist.size() > 0)
00556                             {
00557                                 //component per color...obviously we assume they are RGB or RGBA if ARGB you get fancy effects....
00558                                 if (accesslist.at(0).childNodes().size() == 4)
00559                                     m.vert[vv].C() = vcg::Color4b(geosrcvertcol[ii * 4].toFloat()*255.0,geosrcvertcol[ii * 4 + 1].toFloat()*255.0,geosrcvertcol[ii * 4 + 2].toFloat()*255.0,geosrcvertcol[ii * 4 + 3].toFloat()*255.0);
00560                                 else
00561                                     if (accesslist.at(0).childNodes().size() == 3)
00562                                         m.vert[vv].C() = vcg::Color4b(geosrcvertcol[ii * 3].toFloat()*255.0,geosrcvertcol[ii * 3 + 1].toFloat()*255.0,geosrcvertcol[ii * 3 + 2].toFloat()*255.0,255.0);
00563                             }
00564                         }
00565 
00566                         if (!srcnodetext.isNull())
00567                         {
00568 
00569                             assert((ii * 2 < geosrcverttext.size()) && (ii * 2 + 1 < geosrcverttext.size()));
00570                             m.vert[vv].T() = vcg::TexCoord2<float>();
00571                             m.vert[vv].T().u() = geosrcverttext[ii * 2].toFloat();
00572                             m.vert[vv].T().v() = geosrcverttext[ii * 2 + 1].toFloat();
00573                         }
00574                         ++ii;
00575                     }
00576 
00577                     QDomNodeList tripatch = geo.toElement().elementsByTagName("triangles");
00578                     QDomNodeList polypatch = geo.toElement().elementsByTagName("polygons");
00579                     QDomNodeList polylist = geo.toElement().elementsByTagName("polylist");
00580                     QStringList vertcount;
00581                     valueStringList(vertcount,polylist.at(0),"vcount");
00582                     int isTri=true;
00583                     for (int i=0; i<vertcount.size(); i++)
00584                     {
00585                         if (vertcount[i]!="3")
00586                         {
00587                             isTri=false;
00588                             break;
00589                         }
00590 
00591                     }
00592                     if (isTri && tripatch.isEmpty())
00593                         tripatch=polylist;
00594                     if (tripatch.isEmpty()  && polypatch.isEmpty() && polylist.isEmpty())
00595                         return E_NOPOLYGONALMESH;
00596 
00597                     DAEError err = E_NOERROR;
00598                     err = LoadTriangularMesh(tripatch,m,offset,info,materialBinding);
00599                     //err = LoadPolygonalMesh(polypatch,m,offset,info);
00600             //                                  err = OldLoadPolygonalListMesh(polylist,m,offset,info);
00601                     err = LoadPolygonalListMesh(polylist,m,offset,info,materialBinding);
00602                     if (err != E_NOERROR)
00603                         return err;
00604                 }
00605             QDEBUG("**** Loading a Geometry Mesh **** (final   mesh size %i %i - %i %i)",m.vn,m.vert.size(),m.fn,m.face.size());
00606             return E_NOERROR;
00607         }
00608 
00609         static void GetTexCoord(const QDomDocument& doc, QStringList &texturefile)
00610         {
00611             QDomNodeList txlst = doc.elementsByTagName("library_images");
00612             for(int img = 0;img < txlst.at(0).childNodes().size();++img)
00613             {
00614                 QDomNodeList nlst = txlst.at(0).childNodes().at(img).toElement().elementsByTagName("init_from");
00615                 if (nlst.size() > 0)
00616                 {
00617                                     texturefile.push_back( nlst.at(0).firstChild().nodeValue());
00618                 }
00619             }
00620         }
00621 
00622     // This recursive function add to a mesh the subtree starting from the passed node.
00623     // When you start from a visual_scene, you can find nodes.
00624   // nodes can be directly instanced or referred from the node library.
00625 
00626         static void AddNodeToMesh(QDomElement node,
00627                                                             ColladaMesh& m, Matrix44f curTr,
00628                                                             InfoDAE& info)
00629         {
00630                 QDEBUG("Starting processing <node> with id %s",qPrintable(node.attribute("id")));
00631 
00632                 curTr = curTr * getTransfMatrixFromNode(node);
00633 
00634                 QDomNodeList geomNodeList = node.elementsByTagName("instance_geometry");
00635                 for(int ch = 0;ch < geomNodeList.size();++ch)
00636                 {
00637                     QDomElement instGeomNode= geomNodeList.at(ch).toElement();
00638                     if(instGeomNode.parentNode()==node) // process only direct child
00639                     {
00640                         QDEBUG("** instance_geometry with url %s (intial mesh size %i %i T = %i)",qPrintable(instGeomNode.attribute("url")),m.vn,m.fn,m.textures.size());
00641                         //assert(m.textures.size()>0 == HasPerWedgeTexCoord(m));
00642                         QString geomNode_url;
00643                         referenceToANodeAttribute(instGeomNode,"url",geomNode_url);
00644                         QDomNode refNode = findNodeBySpecificAttributeValue(*(info.doc),"geometry","id",geomNode_url);
00645                         QDomNodeList bindingNodes = instGeomNode.toElement().elementsByTagName("bind_material");
00646                         QMap<QString,QString> materialBindingMap;
00647                         if(     bindingNodes.size()>0) {
00648                             QDEBUG("**    instance_geometry has a material binding");
00649                             GenerateMaterialBinding(instGeomNode,materialBindingMap);
00650                         }
00651 
00652                         ColladaMesh newMesh;
00653 //                                              newMesh.face.EnableWedgeTex();
00654                         LoadGeometry(newMesh, info, refNode.toElement(),materialBindingMap);
00655                         tri::UpdatePosition<ColladaMesh>::Matrix(newMesh,curTr);
00656                         tri::Append<ColladaMesh,ColladaMesh>::Mesh(m,newMesh);
00657                         QDEBUG("** instance_geometry with url %s (final mesh size %i %i - %i %i)",qPrintable(instGeomNode.attribute("url")),m.vn,m.vert.size(),m.fn,m.face.size());
00658                     }
00659                 }
00660 
00661                 QDomNodeList controllerNodeList = node.elementsByTagName("instance_controller");
00662                 for(int ch = 0;ch < controllerNodeList.size();++ch)
00663                 {
00664                     QDomElement instContrNode= controllerNodeList.at(ch).toElement();
00665                     if(instContrNode.parentNode()==node) // process only direct child
00666                     {
00667                         QDEBUG("Found a instance_controller with url %s",qPrintable(instContrNode.attribute("url")));
00668 
00669                         QString controllerNode_url;
00670                         referenceToANodeAttribute(instContrNode,"url",controllerNode_url);
00671                         QDEBUG("Found a instance_controller with url '%s'", qPrintable(controllerNode_url));
00672                         QDomNode refNode = findNodeBySpecificAttributeValue(*(info.doc),"controller","id",controllerNode_url);
00673 
00674                         QDomNodeList bindingNodes = instContrNode.toElement().elementsByTagName("bind_material");
00675                         QMap<QString, QString> materialBindingMap;
00676                             if( bindingNodes.size()>0) {
00677                             QDEBUG("**   instance_controller node of has a material binding");
00678                             GenerateMaterialBinding(instContrNode,materialBindingMap);
00679                         }
00680 
00681                         ColladaMesh newMesh;
00682                         LoadControllerMesh(newMesh, info, refNode.toElement(),materialBindingMap);
00683                         tri::UpdatePosition<ColladaMesh>::Matrix(newMesh,curTr);
00684                         tri::Append<ColladaMesh,ColladaMesh>::Mesh(m,newMesh);
00685                     }
00686                 }
00687 
00688                 QDomNodeList nodeNodeList = node.elementsByTagName("node");
00689                 for(int ch = 0;ch < nodeNodeList.size();++ch)
00690                 {
00691                     if(nodeNodeList.at(ch).parentNode()==node) // process only direct child
00692                             AddNodeToMesh(nodeNodeList.at(ch).toElement(), m,curTr, info);
00693                 }
00694 
00695                 QDomNodeList instanceNodeList = node.elementsByTagName("instance_node");
00696                 for(int ch = 0;ch < instanceNodeList.size();++ch)
00697                 {
00698                     if(instanceNodeList.at(ch).parentNode()==node) // process only direct child
00699                     {
00700                         QDomElement instanceNode =  instanceNodeList.at(ch).toElement();
00701                         QString node_url;
00702                         referenceToANodeAttribute(instanceNode,"url",node_url);
00703                         QDEBUG("Found a instance_node with url '%s'", qPrintable(node_url));
00704                         QDomNode refNode = findNodeBySpecificAttributeValue(*(info.doc),"node","id",node_url);
00705                         if(refNode.isNull())
00706                             QDEBUG("findNodeBySpecificAttributeValue returned a null node for %s",qPrintable(node_url));
00707 
00708                         AddNodeToMesh(refNode.toElement(), m,curTr, info);
00709                     }
00710                 }
00711         }
00712 
00713 
00714 // Retrieve the transformation matrix that is defined in the childs of a node.
00715 // used during the recursive descent.
00716 static Matrix44f getTransfMatrixFromNode(const QDomElement parentNode)
00717 {
00718     QDEBUG("getTrans form node with tag %s",qPrintable(parentNode.tagName()));
00719     assert(parentNode.tagName() == "node");
00720 
00721     std::vector<QDomNode> rotationList;
00722     QDomNode matrixNode;
00723     QDomNode translationNode;
00724     for(int ch = 0;ch < parentNode.childNodes().size();++ch)
00725         {
00726             if (parentNode.childNodes().at(ch).nodeName() == "rotate")
00727                 rotationList.push_back(parentNode.childNodes().at(ch));
00728             if (parentNode.childNodes().at(ch).nodeName() == "translate")
00729                 translationNode = parentNode.childNodes().at(ch);
00730             if (parentNode.childNodes().at(ch).nodeName() == "matrix")
00731                 matrixNode = parentNode.childNodes().at(ch);
00732         }
00733 
00734         Matrix44f rotM;            rotM.SetIdentity();
00735         Matrix44f transM; transM.SetIdentity();
00736 
00737         if (!translationNode.isNull()) ParseTranslation(transM,translationNode);
00738         if (!rotationList.empty()) ParseRotationMatrix(rotM,rotationList);
00739         if (!matrixNode.isNull())
00740         {
00741             ParseMatrixNode(transM,matrixNode);
00742           return transM;
00743         }
00744       return transM*rotM;
00745 }
00746 
00747     public:
00748 
00749         //merge all meshes in the collada's file in the templeted mesh m
00750         //I assume the mesh
00751 
00752         static int Open(OpenMeshType& m,const char* filename, InfoDAE& info, CallBackPos *cb=0)
00753         {
00754             (void)cb;
00755 
00756             QDEBUG("----- Starting the processing of %s ------",filename);
00757             //AdditionalInfoDAE& inf = new AdditionalInfoDAE();
00758             //info = new InfoDAE();
00759 
00760             QDomDocument* doc = new QDomDocument(filename);
00761             info.doc = doc;
00762             QFile file(filename);
00763             if (!file.open(QIODevice::ReadOnly))
00764                 return E_CANTOPEN;
00765             if (!doc->setContent(&file))
00766             {
00767                 file.close();
00768                 return E_CANTOPEN;
00769             }
00770             file.close();
00771 
00772             //GetTexture(*(info.doc),inf);
00773 
00774 //                      GenerateMaterialToTextureMap(info);
00775             //scene->instance_visual_scene
00776             QDomNodeList scenes = info.doc->elementsByTagName("scene");
00777             int scn_size = scenes.size();
00778             if (scn_size == 0)
00779                 return E_NO3DSCENE;
00780             QDEBUG("File Contains %i Scenes",scenes.size());
00781             int problem = E_NOERROR;
00782             //bool found_a_mesh = false;
00783             //Is there geometry in the file?
00784             //bool geoinst_found = false;
00785 
00786             // The main loading loop
00787             // for each scene in COLLADA FILE
00788             /*
00789             Some notes on collada structure.
00790             top level nodes are :
00791             <asset>
00792             <library_images>
00793             <library_materials>
00794             <library_effects>
00795             <library_geometries>
00796             <library_visual_scene>
00797             <scene>
00798 
00799             The REAL top root is the <scene> that can contains one of more (instance of) <visual_scene>.
00800             <visual_scene> can be directly written there (check!) or instanced from their definition in the <library_visual_scene>
00801             each <visual_scene> contains a hierarchy of <node>
00802           each <node> contains
00803                 transformation
00804                 other nodes (to build up a hierarchy)
00805                 instance of geometry
00806                 instance of controller
00807             instance can be direct or refers name of stuff described in a library.
00808             An instance of geometry node should contain the <mesh> node and as a son of the <instance geometry> the material node (again referenced from a library)
00809             -- structure of the geometry node --
00810             */
00811             for(int scn = 0;scn < scn_size;++scn)
00812             {
00813                 QDomNodeList instscenes = scenes.at(scn).toElement().elementsByTagName("instance_visual_scene");
00814                 int instscn_size = instscenes.size();
00815                 QDEBUG("Scene %i contains %i instance_visual_scene ",scn,instscn_size);
00816                 if (instscn_size == 0)  return E_INCOMPATIBLECOLLADA141FORMAT;
00817 
00818                 //for each scene instance in a COLLADA scene
00819                 for(int instscn = 0;instscn < instscn_size; ++instscn)
00820                 {
00821                     QString libscn_url;
00822                     referenceToANodeAttribute(instscenes.at(instscn),"url",libscn_url);
00823                     QDEBUG("instance_visual_scene %i refers %s ",instscn,qPrintable(libscn_url));
00824 
00825 //                                      QDomNode nd = QDomNode(*(inf->doc));
00826                     QDomNode visscn = findNodeBySpecificAttributeValue(*(info.doc),"visual_scene","id",libscn_url);
00827                     if(visscn.isNull()) return E_UNREFERENCEBLEDCOLLADAATTRIBUTE;
00828 
00829                     //assert (visscn.toElement().Attribute("id") == libscn_url);
00830                     //for each node in the libscn_url visual scene
00831                     QDomNodeList visscn_child = visscn.childNodes();
00832                     QDEBUG("instance_visual_scene %s has %i children",qPrintable(libscn_url),visscn_child.size());
00833 
00834                     // for each direct child of a visual scene process it
00835                     for(int chdind = 0; chdind < visscn_child.size();++chdind)
00836                     {
00837                         QDomElement node=visscn_child.at(chdind).toElement();
00838                         if(node.isNull()) continue;
00839                         QDEBUG("Processing Visual Scene child %i - of type '%s'",chdind,qPrintable(node.tagName()));
00840                         Matrix44f baseTr; baseTr.SetIdentity();
00841 
00842                         if(node.toElement().tagName()=="node")
00843                         {
00844                             ColladaMesh newMesh;
00845                             AddNodeToMesh(node.toElement(), newMesh, baseTr,info);
00846                             tri::Append<OpenMeshType,ColladaMesh>::Mesh(m,newMesh);
00847                         }
00848                     }   // end for each node of a given scene
00849                 } // end for each visual scene instance
00850             } // end for each scene instance
00851             return problem;
00852         }
00853 
00854         static bool LoadMask(const char * filename, InfoDAE& info)
00855         {
00856             bool bHasPerWedgeTexCoord = false;
00857             bool bHasPerWedgeNormal             = false;
00858             //bool bHasPerWedgeColor            = false;
00859             bool bHasPerVertexColor             = false;
00860             bool bHasPerFaceColor                       = false;
00861             bool bHasPerVertexNormal = false;
00862             bool bHasPerVertexText = false;
00863 
00864             QDomDocument* doc = new QDomDocument(filename);
00865             QFile file(filename);
00866             if (!file.open(QIODevice::ReadOnly))
00867                 return false;
00868             if (!doc->setContent(&file))
00869             {
00870                 file.close();
00871                 return false;
00872             }
00873             file.close();
00874 
00875             QStringList textureFileList;
00876             info.doc = doc;
00877             GetTexCoord(*(info.doc),textureFileList);
00878             QDomNodeList scenes = info.doc->elementsByTagName("scene");
00879             int scn_size = scenes.size();
00880 
00881 
00882             //Is there geometry in the file?
00883             bool geoinst_found = false;
00884             //for each scene in COLLADA FILE
00885             for(int scn = 0;scn < scn_size;++scn)
00886             {
00887                 QDomNodeList instscenes = scenes.at(scn).toElement().elementsByTagName("instance_visual_scene");
00888                 int instscn_size = instscenes.size();
00889                 if (instscn_size == 0)  return false;
00890 
00891                 //for each scene instance in a COLLADA scene
00892                 for(int instscn = 0;instscn < instscn_size; ++instscn)
00893                 {
00894                     QString libscn_url;
00895                     referenceToANodeAttribute(instscenes.at(instscn),"url",libscn_url);
00896                     QDomNode nd = QDomNode(*(info.doc));
00897                     QDomNode visscn = findNodeBySpecificAttributeValue(*(info.doc),"visual_scene","id",libscn_url);
00898                     if(visscn.isNull())         return false;
00899 
00900                     //for each node in the libscn_url visual scene
00901                     //QDomNodeList& visscn_child = visscn.childNodes();
00902                     QDomNodeList visscn_child = visscn.childNodes();
00903 
00904                     //for each direct child of a libscn_url visual scene find if there is some geometry instance
00905                     for(int chdind = 0; chdind < visscn_child.size();++chdind)
00906                     {
00907                         //QDomNodeList& geoinst = visscn_child.at(chdind).toElement().elementsByTagName("instance_geometry");
00908                         QDomNodeList geoinst = visscn_child.at(chdind).toElement().elementsByTagName("instance_geometry");
00909                         int geoinst_size = geoinst.size();
00910                         if (geoinst_size != 0)
00911                         {
00912 
00913                             geoinst_found |= true;
00914                             QDomNodeList geolib = info.doc->elementsByTagName("library_geometries");
00915                             //assert(geolib.size() == 1);
00916                             if (geolib.size() != 1)
00917                                 return false;
00919                             info.numvert = 0;
00920                             info.numface = 0;
00921                             for(int geoinst_ind = 0;geoinst_ind < geoinst_size;++geoinst_ind)
00922                             {
00923                                 QString geo_url;
00924                                 referenceToANodeAttribute(geoinst.at(geoinst_ind),"url",geo_url);
00925 
00926                                 QDomNode geo = findNodeBySpecificAttributeValue(geolib.at(0),"geometry","id",geo_url);
00927                                 if (geo.isNull())
00928                                     return false;
00929 
00930                                 QDomNodeList vertlist = geo.toElement().elementsByTagName("vertices");
00931 
00932                                 for(int vert = 0;vert < vertlist.size();++vert)
00933                                 {
00934                                     QDomNode no;
00935                                     no = findNodeBySpecificAttributeValue(vertlist.at(vert),"input","semantic","POSITION");
00936                                     QString srcurl;
00937                                     referenceToANodeAttribute(no,"source",srcurl);
00938                                     no = findNodeBySpecificAttributeValue(geo,"source","id",srcurl);
00939                                     QDomNodeList fa = no.toElement().elementsByTagName("float_array");
00940                                     assert(fa.size() == 1);
00941                                     info.numvert += (fa.at(0).toElement().attribute("count").toInt() / 3);
00942                                     no = findNodeBySpecificAttributeValue(vertlist.at(vert),"input","semantic","COLOR");
00943                                     if (!no.isNull())
00944                                         bHasPerVertexColor = true;
00945                                     no = findNodeBySpecificAttributeValue(vertlist.at(vert),"input","semantic","NORMAL");
00946                                     if (!no.isNull())
00947                                         bHasPerVertexNormal = true;
00948                                     no = findNodeBySpecificAttributeValue(vertlist.at(vert),"input","semantic","TEXCOORD");
00949                                     if (!no.isNull())
00950                                         bHasPerVertexText = true;
00951                                 }
00952 
00953                                 const char* arr[] = {"triangles","polylist","polygons"};
00954 
00955                                 for(unsigned int tt= 0;tt < 3;++tt)
00956                                 {
00957                                     QDomNodeList facelist = geo.toElement().elementsByTagName(arr[tt]);
00958                                     for(int face = 0;face < facelist.size();++face)
00959                                     {
00960                                         info.numface += facelist.at(face).toElement().attribute("count").toInt() ;
00961                                         QDomNode no;
00962                                         no = findNodeBySpecificAttributeValue(facelist.at(face),"input","semantic","NORMAL");
00963                                         if (!no.isNull())
00964                                             bHasPerWedgeNormal = true;
00965                                         no = findNodeBySpecificAttributeValue(facelist.at(face),"input","semantic","COLOR");
00966                                         if (!no.isNull())
00967                                             bHasPerVertexColor = true;
00968                                         no = findNodeBySpecificAttributeValue(facelist.at(face),"input","semantic","TEXCOORD");
00969                                         if (!no.isNull())
00970                                             bHasPerWedgeTexCoord = true;
00971                                     }
00972                                 }
00973                             }
00974                         }
00975                     }
00976                 }
00977             }
00978 
00979             if (!geoinst_found)
00980             {
00981                 QDomNodeList geolib = info.doc->elementsByTagName("library_geometries");
00982                 //assert(geolib.size() == 1);
00983                 if (geolib.size() != 1)
00984                     return false;
00985                 QDomNodeList geochild = geolib.at(0).toElement().elementsByTagName("geometry");
00987                 info.numvert = 0;
00988                 info.numface = 0;
00989                 for(int geoinst_ind = 0;geoinst_ind < geochild.size();++geoinst_ind)
00990                 {
00991                     QDomNodeList vertlist = geochild.at(geoinst_ind).toElement().elementsByTagName("vertices");
00992 
00993                     for(int vert = 0;vert < vertlist.size();++vert)
00994                     {
00995                         QDomNode no;
00996                         no = findNodeBySpecificAttributeValue(vertlist.at(vert),"input","semantic","POSITION");
00997                         QString srcurl;
00998                         referenceToANodeAttribute(no,"source",srcurl);
00999                         no = findNodeBySpecificAttributeValue(geochild.at(geoinst_ind),"source","id",srcurl);
01000                         QDomNodeList fa = no.toElement().elementsByTagName("float_array");
01001                         assert(fa.size() == 1);
01002                         info.numvert += (fa.at(0).toElement().attribute("count").toInt() / 3);
01003                         no = findNodeBySpecificAttributeValue(vertlist.at(vert),"input","semantic","COLOR");
01004                         if (!no.isNull())
01005                             bHasPerVertexColor = true;
01006                         no = findNodeBySpecificAttributeValue(vertlist.at(vert),"input","semantic","NORMAL");
01007                         if (!no.isNull())
01008                             bHasPerVertexNormal = true;
01009                         no = findNodeBySpecificAttributeValue(vertlist.at(vert),"input","semantic","TEXCOORD");
01010                         if (!no.isNull())
01011                             bHasPerVertexText = true;
01012                     }
01013 
01014                     QDomNodeList facelist = geochild.at(geoinst_ind).toElement().elementsByTagName("triangles");
01015                     for(int face = 0;face < facelist.size();++face)
01016                     {
01017                         info.numface += facelist.at(face).toElement().attribute("count").toInt() ;
01018                         QDomNode no;
01019                         no = findNodeBySpecificAttributeValue(facelist.at(face),"input","semantic","NORMAL");
01020                         if (!no.isNull())
01021                             bHasPerWedgeNormal = true;
01022                         no = findNodeBySpecificAttributeValue(facelist.at(face),"input","semantic","TEXCOORD");
01023                         if (!no.isNull())
01024                             bHasPerWedgeTexCoord = true;
01025                     }
01026                 }
01027             }
01028 
01029             info.mask = 0;
01030 
01031             if (bHasPerWedgeTexCoord)
01032                 info.mask |= vcg::tri::io::Mask::IOM_WEDGTEXCOORD;
01033             if (bHasPerWedgeNormal)
01034                 info.mask |= vcg::tri::io::Mask::IOM_WEDGNORMAL;
01035             if (bHasPerVertexColor)
01036                 info.mask |= vcg::tri::io::Mask::IOM_VERTCOLOR;
01037             if (bHasPerFaceColor)
01038                 info.mask |= vcg::tri::io::Mask::IOM_FACECOLOR;
01039             if (bHasPerVertexNormal)
01040                 info.mask |= vcg::tri::io::Mask::IOM_VERTNORMAL;
01041             if (bHasPerVertexText)
01042                 info.mask |= vcg::tri::io::Mask::IOM_VERTTEXCOORD;
01043 
01044 
01045 
01046             delete (info.doc);
01047             info.doc = NULL;
01048             //addinfo = info;
01049             return true;
01050         }
01051     };
01052 }
01053 }
01054 }
01055 
01056 #endif


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:31:55