util_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 #ifndef __VCGLIB_UTILDAE
00024 #define __VCGLIB_UTILDAE
00025 
00026 
00027 #include <vcg/complex/append.h>
00028 #include <wrap/io_trimesh/additionalinfo.h>
00029 #include <vcg/complex/algorithms/update/normal.h>
00030 #include <vcg/complex/algorithms/update/position.h>
00031 
00032 #include <wrap/io_trimesh/io_mask.h>
00033 
00034 #include <QDomDocument>
00035 #include <QFile>
00036 #include <QXmlStreamWriter>
00037 #include <QStringList>
00038 #include <QMap>
00039 
00040 #include <vcg/space/point3.h>
00041 #include <vcg/space/texcoord2.h>
00042 #include <vcg/space/color4.h>
00043 #include <vcg/space/texcoord2.h>
00044 #include <wrap/callback.h>
00045 
00046 #include <vector>
00047 
00048 namespace vcg {
00049 namespace tri {
00050 namespace io {
00051         class InfoDAE  : public AdditionalInfo
00052         {
00053                 public:
00054                 
00055                 InfoDAE() :AdditionalInfo(){
00056                         doc = NULL;
00057                         textureIdMap.clear();
00058                 }
00059 
00060                 ~InfoDAE(){
00061                         if(doc!=NULL) delete doc;
00062                 }
00063 
00064                 QDomDocument* doc;              
00065                 QMap<QString,int> textureIdMap;
00066         };
00067 
00068         class UtilDAE
00069         {
00070         public:
00071                 enum DAEError 
00072                 {
00073                         E_NOERROR,                              // 0
00074                         E_CANTOPEN,                             // 1
00075                         E_NOGEOMETRYLIBRARY,     // 2 
00076                         E_NOMESH,      // 3
00077                         E_NOVERTEXPOSITION,            // 4
00078                         E_NO3DVERTEXPOSITION,                   // 5
00079                         E_NO3DSCENE, // 6
00080                         E_INCOMPATIBLECOLLADA141FORMAT, //7
00081                         E_UNREFERENCEBLEDCOLLADAATTRIBUTE, // 8
00082                         E_NOPOLYGONALMESH, //9
00083                         E_CANTSAVE, //10
00084                         E_NOACCESSORELEMENT
00085                 };
00086                 
00087 
00088                 static const char *ErrorMsg(int error)
00089                 {
00090                         static const char * dae_error_msg[] =
00091                         {
00092                                 "No errors",
00093                                 "Can't open file",
00094                                 "File without a geometry library",
00095                                 "There isn't mesh in file",
00096                                 "The meshes in file haven't the vertex position attribute",
00097                                 "The importer assumes that the OpenMeshType uses a 3D point for the vertex position",
00098                                 "There isn't any scene in Collada file",
00099                                 "The input file is not compatible with COLLADA 1.41 standard format",
00100                                 "Collada file is trying to referece an attribute that is not in the file",
00101                                 "This version of Collada Importer support only triangular and polygonal mesh file"
00102                         };
00103 
00104                         if(error>9 || error<0) return "Unknown error";
00105                         else return dae_error_msg[error];
00106                 };
00107         protected:
00108                 // This function take care of removing the standard '#' from the beginning of the url
00109                 // For example 
00110           // <instance_geometry url="#shape0-lib">
00111                 // means that you have to search in the <library_geometries> for a node <geometry> with id = "shape0-lib"
00112                 // you have to call this function to get ther right refernece name
00113 
00114                 inline static void referenceToANodeAttribute(const QDomNode n,const QString& attr,QString& url_st)
00115                 {
00116                         url_st = n.toElement().attribute(attr);
00117                         int sz = url_st.size() - 1;
00118                         url_st = url_st.right(sz);
00119                         assert(url_st.size() != 0);
00120                 }
00121 
00122                 inline static QDomNode findNodeBySpecificAttributeValue(const QDomNodeList& ndl,const QString& attrname,const QString& attrvalue)
00123                 {
00124                         int ndl_size = ndl.size();
00125                         int ind = 0;
00126                         while(ind < ndl_size)
00127                         {
00128                                 QString st = ndl.at(ind).toElement().attribute(attrname);
00129                                 if (st == attrvalue)
00130                                         return ndl.at(ind);
00131                                 ++ind;
00132                         }
00133                         return QDomNode();
00134                 }
00135 
00136                 inline static QDomNode findNodeBySpecificAttributeValue(const QDomNode n,const QString& tag,const QString& attrname,const QString& attrvalue)
00137                 {
00138                         return findNodeBySpecificAttributeValue(n.toElement().elementsByTagName(tag),attrname,attrvalue);
00139                 }
00140 
00141                 inline static QDomNode findNodeBySpecificAttributeValue(const QDomDocument n,const QString& tag,const QString& attrname,const QString& attrvalue)
00142                 {
00143                         return findNodeBySpecificAttributeValue(n.elementsByTagName(tag),attrname,attrvalue);
00144                 }
00145                 
00146                 inline static bool isThereTag(const QDomNodeList& list)
00147                 {
00148                         return ((list.size() > 0) ? true : false);
00149                 }
00150 
00151                 inline static bool isThereTag(const QDomNode n,const QString& tagname)
00152                 {
00153                         return isThereTag(n.toElement().elementsByTagName(tagname));
00154                 }
00155 
00156                 inline static bool isThereTag(const QDomDocument n,const QString& tagname)
00157                 {
00158                         return isThereTag(n.elementsByTagName(tagname));
00159                 }
00160 
00161     // Very important function that given a <vertices> element find one of the its attribute (like position, color etc)
00162                 inline static QDomNode attributeSourcePerSimplex(const QDomNode n,const QDomDocument startpoint,const QString& sem)
00163                 {
00164                         QDomNodeList vertattr = n.toElement().elementsByTagName("input");
00165                         for(int ind = 0;ind < vertattr.size();++ind)
00166                         {
00167                                 if (vertattr.at(ind).toElement().attribute("semantic") == sem)
00168                                 {
00169                                         QString url; 
00170                                         referenceToANodeAttribute(vertattr.at(ind),"source",url);
00171                                         return findNodeBySpecificAttributeValue(startpoint,"source","id",url);
00172                                 }
00173                         }
00174                         return QDomNode();
00175                 }
00176 
00177                 // This function is used to build up a list of strings that are scalar values.
00178                 inline static void valueStringList(QStringList& res,const QDomNode srcnode,const QString& tag) 
00179                 {
00180                         QDomNodeList list = srcnode.toElement().elementsByTagName(tag);
00181                         //assert(list.size() == 1);
00182                         QString nd = list.at(0).firstChild().nodeValue();
00183                         res = nd.simplified().split(" ",QString::SkipEmptyParts);
00184             if(res.empty())
00185                 {
00186                     qDebug("Warning valueStringList returned and emtpy list. nothing inside element with tag '%s'", qPrintable(tag));
00187                     return;
00188                 }
00189                         if (res.last() == "")
00190                                 res.removeLast();
00191                 
00192 //                      int emptyCount = res.removeAll(QString(""));
00193 //                      if(emptyCount>0) qDebug("- - - - - - - - valueStringList: Removed %i null strings when parsing tag %s",emptyCount,qPrintable(tag));
00194 //                      for(int i =0;i<res.size();++i)
00195 //                              qDebug("- - - - - - - - - - - - %3i = '%s'",i,qPrintable(res.at(i)));
00196                 
00197                 }
00198 
00199                 /*inline static bool removeChildNode(QDomNodeList*/
00200                 
00201                 inline static bool removeChildNodeList(QDomNodeList& nodelst,const QString& tag = "", const QString& attribname = "", const QString& attribvalue = "")
00202                 {
00203                         for(int jj = 0;jj < nodelst.size();++jj)
00204                         {
00205                                 removeChildNode(nodelst.at(jj),tag,attribname,attribvalue); 
00206                         }
00207                         return true;
00208                 }
00209 
00210 
00211                 inline static bool removeChildNode(QDomNode node,const QString& tag = "", const QString& attribname = "", const QString& attribvalue = "")
00212                 {
00213                         QDomNodeList clst = node.childNodes();
00214                         for(int ii = 0;ii < clst.size();++ii)
00215                         {
00216                                 QDomNode oldchild = node.childNodes().at(ii); 
00217                                 if (tag != "")
00218                                 {
00219                                         if ((attribname != "") && (attribvalue != ""))
00220                                         {
00221                                                 if (clst.at(ii).toElement().attribute(attribname) == attribvalue)
00222                                                         node.removeChild(oldchild);
00223                                         }
00224                                         else 
00225                                         {       
00226                                                 QString nm = clst.at(ii).nodeName();
00227                                                 if (clst.at(ii).nodeName() == tag) 
00228                                                 {
00229                                                         node.removeChild(oldchild);
00230                                                 }
00231                                         }
00232                                 }
00233                                 else node.removeChild(oldchild);
00234                         }
00235                         return true;
00236                 }
00237 
00238                 static void ParseRotationMatrix(vcg::Matrix44f& m,const std::vector<QDomNode>& t)
00239                 {
00240                         vcg::Matrix44f rotTmp;
00241                         vcg::Matrix44f tmp;
00242                         rotTmp.SetIdentity();
00243                         tmp.SetIdentity();
00244                         for(unsigned int ii = 0;ii < t.size();++ii)
00245                         {
00246                                 QString rt = t[ii].firstChild().nodeValue();
00247                                 QStringList rtl = rt.split(" ");
00248                                 if (rtl.last() == "") rtl.removeLast();
00249                                 assert(rtl.size() == 4);
00250                                 tmp.SetRotateDeg(rtl.at(3).toFloat(),vcg::Point3f(rtl.at(0).toFloat(),rtl.at(1).toFloat(),rtl.at(2).toFloat()));
00251                                 rotTmp = rotTmp*tmp;    
00252                         }
00253                         m = m * rotTmp;
00254                 }
00255 
00256                 static void ParseTranslation(vcg::Matrix44f& m,const QDomNode t)
00257                 {
00258                         assert(t.toElement().tagName() == "translate");
00259                         QDomNode tr = t.firstChild();
00260                         QString coord = tr.nodeValue();
00261                         QStringList coordlist = coord.split(" ");
00262                         if (coordlist.last() == "") 
00263                                 coordlist.removeLast();
00264                         assert(coordlist.size() == 3);
00265                         m[0][0] = 1.0f;
00266                         m[1][1] = 1.0f;
00267                         m[2][2] = 1.0f;
00268                         m[3][3] = 1.0f;
00269                         m[0][3] = coordlist.at(0).toFloat();
00270                         m[1][3] = coordlist.at(1).toFloat();
00271                         m[2][3] = coordlist.at(2).toFloat();
00272                 }
00273                 
00274                 static void ParseMatrixNode(vcg::Matrix44f& m,const QDomNode t)
00275                 {
00276                         assert(t.toElement().tagName() == "matrix");
00277                         QDomNode tr = t.firstChild();
00278                         QString coord = tr.nodeValue().simplified();
00279                         qDebug("Parsing matrix node; text value is '%s'",qPrintable(coord));
00280                         QStringList coordlist = coord.split(" ");
00281                         if (coordlist.last() == "") 
00282                                 coordlist.removeLast();
00283                         assert(coordlist.size() == 16);
00284                         for(int i=0;i<4;++i)
00285                         {
00286                                 m[i][0] = coordlist.at(i*4+0).toFloat();
00287                                 m[i][1] = coordlist.at(i*4+1).toFloat();
00288                                 m[i][2] = coordlist.at(i*4+2).toFloat();
00289                                 m[i][3] = coordlist.at(i*4+3).toFloat();
00290                         }
00291                 }
00292 
00293                 static void TransfMatrix(const QDomNode parentnode,const QDomNode presentnode,vcg::Matrix44f& m)
00294                 {
00295                         if (presentnode == parentnode) return;
00296                         else
00297                         {
00298                                 QDomNode par = presentnode.parentNode();
00299                                 std::vector<QDomNode> rotlist;
00300                                 QDomNode trans;
00301                                 for(int ch = 0;ch < par.childNodes().size();++ch)
00302                                 {
00303                                         if (par.childNodes().at(ch).nodeName() == "rotate")
00304                                                 rotlist.push_back(par.childNodes().at(ch));
00305                                         else if (par.childNodes().at(ch).nodeName() == "translate")
00306                                                  {
00307                                                         trans = par.childNodes().at(ch);
00308                                              }          
00309                                 }
00310                                 vcg::Matrix44f tmp;
00311                                 tmp.SetIdentity();
00312                                 if (!trans.isNull()) ParseTranslation(tmp,trans);
00313                                 ParseRotationMatrix(tmp,rotlist);
00314                                 m = m * tmp;
00315                                 TransfMatrix(parentnode,par,m);
00316                         }
00317                 }
00318 
00319                 inline static int findOffSetForASingleSimplex(QDomNode node)
00320                 {
00321                         QDomNodeList wedatts = node.toElement().elementsByTagName("input");
00322                         int max = 0;
00323                         if (wedatts.size() == 0) return -1;
00324                         else 
00325                         {
00326                                 for(int ii = 0;ii < wedatts.size();++ii)
00327                                 {
00328                                         int tmp = wedatts.at(ii).toElement().attribute("offset").toInt();
00329                                         if (tmp > max) max = tmp;
00330                                 }
00331                         }
00332                         return max + 1;
00333                 }
00334 
00335                 inline static int findStringListAttribute(QStringList& list,const QDomNode node,const QDomNode poly,const QDomDocument startpoint,const char* token)
00336                 {
00337                         int offset = 0;
00338                         if (!node.isNull())
00339                         {
00340                                 offset = node.toElement().attribute("offset").toInt();
00341                                 QDomNode st = attributeSourcePerSimplex(poly,startpoint,token);
00342                                 valueStringList(list,st,"float_array");
00343                         }
00344                         return offset;
00345                 }
00346 
00347                 
00348                 
00349                 
00350                 
00351                 /* Very important procedure 
00352                         it has the task to finde the name of the image node corresponding to a given material id, 
00353                         it assuemes that the material name that is passed have already been bound with the current bindings  
00354                 */
00355                 
00356                 inline static QDomNode textureFinder(QString& boundMaterialName, QString &textureFileName, const QDomDocument doc)
00357                 {
00358                         boundMaterialName.remove('#');
00359                         //library_material -> material -> instance_effect
00360                         QDomNodeList lib_mat = doc.elementsByTagName("library_materials");
00361                         if (lib_mat.size() != 1) 
00362                                 return QDomNode();
00363                         QDomNode material = findNodeBySpecificAttributeValue(lib_mat.at(0),QString("material"),QString("id"),boundMaterialName);
00364                         if (material.isNull()) 
00365                                 return QDomNode();
00366                         QDomNodeList in_eff = material.toElement().elementsByTagName("instance_effect");
00367                         if (in_eff.size() == 0) 
00368                                 return QDomNode();
00369                         QString url = in_eff.at(0).toElement().attribute("url");
00370                         if ((url.isNull()) || (url == ""))
00371                                 return QDomNode();
00372                         url = url.remove('#');
00373       qDebug("====== searching among library_effects the effect with id '%s' ",qPrintable(url));
00374                         //library_effects -> effect -> instance_effect
00375                         QDomNodeList lib_eff = doc.elementsByTagName("library_effects");
00376                         if (lib_eff.size() != 1) 
00377                                 return QDomNode();
00378                         QDomNode effect = findNodeBySpecificAttributeValue(lib_eff.at(0),QString("effect"),QString("id"),url);
00379                         if (effect.isNull()) 
00380                                 return QDomNode();
00381                         QDomNodeList init_from = effect.toElement().elementsByTagName("init_from");
00382                         if (init_from.size() == 0)
00383                                 return QDomNode();
00384                         QString img_id = init_from.at(0).toElement().text();
00385                         if ((img_id.isNull()) || (img_id == ""))
00386                                 return QDomNode();
00387                         
00388                         //library_images -> image
00389                         QDomNodeList libraryImageNodeList = doc.elementsByTagName("library_images");
00390                         qDebug("====== searching among library_images the effect with id '%s' ",qPrintable(img_id));
00391                         if (libraryImageNodeList.size() != 1) 
00392                                 return QDomNode();
00393                         QDomNode imageNode = findNodeBySpecificAttributeValue(libraryImageNodeList.at(0),QString("image"),QString("id"),img_id);
00394                         QDomNodeList initfromNode = imageNode.toElement().elementsByTagName("init_from");
00395                         textureFileName= initfromNode.at(0).firstChild().nodeValue();
00396                         qDebug("====== the image '%s' has a %i init_from nodes text '%s'",qPrintable(img_id),initfromNode.size(),qPrintable(textureFileName));
00397                         
00398                         return imageNode;                       
00399                 }
00400 
00401                 static int indexTextureByImgNode(const QDomDocument doc,const QDomNode node)
00402                 {       
00403                         QDomNodeList libim = doc.elementsByTagName(QString("library_images"));
00404                         if (libim.size() != 1)
00405                                 return -1;
00406                         QDomNodeList imgs = libim.at(0).toElement().elementsByTagName("image");
00407                         
00408                         int ii = 0;
00409                         bool found = false;
00410                         while((ii < imgs.size()) && (!found))
00411                         {
00412                                 if (imgs.at(ii) == node) 
00413                                         found = true;
00414                                 else ++ii;
00415                         }
00416                         if (found) 
00417                                 return ii;
00418                         else
00419                                 return -1;
00420                 }
00421 
00422                 struct WedgeAttribute
00423                 {
00424                         QDomNode wnsrc;
00425                         QStringList wn;
00426                         int offnm;
00427 
00428                         QDomNode wtsrc;
00429                         QStringList wt;
00430                         int stridetx;
00431                         int offtx;
00432 
00433                         QDomNode wcsrc;
00434                         QStringList wc;
00435                         int stridecl;
00436                         int offcl;
00437                 };
00438         };
00439 }
00440 }
00441 }
00442 
00443 #endif


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