/**************************************************************************** * VCGLib o o * * Visual and Computer Graphics Library o o * * _ O _ * * Copyright(C) 2004-2008 \/)\/ * * Visual Computing Lab /\/| * * ISTI - Italian National Research Council | * * \ * * All rights reserved. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * * for more details. * * * ****************************************************************************/ #ifndef _COLLADA_FORMAT_H #define _COLLADA_FORMAT_H #include #include #include #include #include #include template struct CoordNumber{public: static unsigned int coord() { return 0; }}; template struct CoordNumber> { public: static unsigned int coord() { return 2; } }; template struct CoordNumber> { public: static unsigned int coord() { return 3; } }; template struct CoordNumber> { public: static unsigned int coord() { return 4; } }; template<> struct CoordNumber { public: static unsigned int coord() { return 4; } }; namespace Collada { namespace Tags { static const QString testSharp(const QString& str) { QString sharp = ""; if (str.at(0) != '#') sharp = '#'; return (sharp + str); } class ColladaTag : public XMLTag { public: ColladaTag() :XMLTag("COLLADA") { _attributes.push_back(TagAttribute("xmlns","http://www.collada.org/2005/11/COLLADASchema")); _attributes.push_back(TagAttribute("version","1.4.1")); } }; class AssetTag : public XMLTag { public: AssetTag() :XMLTag("asset") { } }; class ContributorTag : public XMLTag { public: ContributorTag() :XMLTag("contributor") { } }; class AuthorTag : public XMLLeafTag { public: AuthorTag() :XMLLeafTag("author") { _text.push_back("VCGLab"); } }; class AuthoringToolTag : public XMLLeafTag { public: AuthoringToolTag() :XMLLeafTag("authoring_tool") { _text.push_back("VCGLib | MeshLab"); } }; class UpAxisTag : public XMLLeafTag { public: UpAxisTag(const QString& up = "Y_UP") :XMLLeafTag("up_axis") { _text.push_back(up); } }; class LibraryImagesTag : public XMLTag { public: LibraryImagesTag() :XMLTag("library_images") { } }; class ImageTag : public XMLTag { public: ImageTag(const QString& id,const QString& name) :XMLTag("image") { _attributes.push_back(TagAttribute("id",id)); _attributes.push_back(TagAttribute("name",name)); } }; class InitFromTag : public XMLLeafTag { public: InitFromTag(const QString& txtpathname) :XMLLeafTag("init_from") { _text.push_back(txtpathname); } }; class LibraryMaterialsTag : public XMLTag { public: LibraryMaterialsTag() :XMLTag("library_materials") { } }; class MaterialTag : public XMLTag { public: MaterialTag(const QString& id,const QString& name) :XMLTag("material") { _attributes.push_back(TagAttribute("id",id)); _attributes.push_back(TagAttribute("name",name)); } }; class InstanceEffectTag : public XMLLeafTag { public: InstanceEffectTag(const QString& url) :XMLLeafTag("instance_effect") { _attributes.push_back(TagAttribute("url",testSharp(url))); } }; class LibraryEffectsTag : public XMLTag { public: LibraryEffectsTag() :XMLTag("library_effects") { } }; class EffectTag : public XMLTag { public: EffectTag(const QString& id) :XMLTag("effect") { _attributes.push_back(TagAttribute("id",id)); } }; class ProfileCommonTag : public XMLTag { public: ProfileCommonTag() :XMLTag("profile_COMMON") { } }; class NewParamTag : public XMLTag { public: NewParamTag(const QString& sid) :XMLTag("newparam") { _attributes.push_back(TagAttribute("sid",sid)); } }; class SurfaceTag : public XMLTag { public: SurfaceTag(const QString& type = QString("2D")) :XMLTag("surface") { _attributes.push_back(TagAttribute("type",type)); } }; class FormatTag : public XMLLeafTag { public: FormatTag(const QString& format) :XMLLeafTag("format") { _text.push_back(format); } }; class Sampler2DTag : public XMLTag { public: Sampler2DTag() :XMLTag("sampler2D") { } }; class SourceTag : public XMLLeafTag { public: SourceTag(const QString& id,const QString& name) :XMLLeafTag("source") { _attributes.push_back(TagAttribute("id",id)); _attributes.push_back(TagAttribute("name",name)); } SourceTag(const QString& source) :XMLLeafTag("source") { _text.push_back(source); } }; class MinFilterTag : public XMLLeafTag { public: MinFilterTag(const QString& filter) :XMLLeafTag("minfilter") { _text.push_back(filter); } }; class MagFilterTag : public XMLLeafTag { public: MagFilterTag(const QString& filter) :XMLLeafTag("magfilter") { _text.push_back(filter); } }; class TechniqueTag : public XMLTag { public: TechniqueTag(const QString& sid) :XMLTag("technique") { _attributes.push_back(TagAttribute("sid",sid)); } }; class TechniqueCommonTag : public XMLTag { public: TechniqueCommonTag() :XMLTag("technique_common") { } }; class BlinnTag : public XMLTag { public: BlinnTag() :XMLTag("blinn") { } }; class EmissionTag : public XMLTag { public: EmissionTag() :XMLTag("emission") { } }; class ColorTag : public XMLLeafTag { public: ColorTag(const float r,const float g,const float b,const float a) :XMLLeafTag("color") { _text.push_back(QString::number(r)); _text.push_back(QString::number(g)); _text.push_back(QString::number(b)); _text.push_back(QString::number(a)); } }; class AmbientTag : public XMLTag { public: AmbientTag() :XMLTag("ambient") { } }; class DiffuseTag : public XMLTag { public: DiffuseTag() :XMLTag("diffuse") { } }; class TextureTag : public XMLLeafTag { public: TextureTag(const QString& texture,const QString& texcoord) :XMLLeafTag("texture") { _attributes.push_back(TagAttribute("texture",texture)); _attributes.push_back(TagAttribute("texcoord",texcoord)); } }; class SpecularTag : public XMLTag { public: SpecularTag() :XMLTag("specular") { } }; class ShininessTag : public XMLTag { public: ShininessTag() :XMLTag("shininess") { } }; class FloatTag : public XMLLeafTag { public: FloatTag(const float floatnum) :XMLLeafTag("float") { _text.push_back(QString::number(floatnum)); } }; class ReflectiveTag : public XMLTag { public: ReflectiveTag() :XMLTag("reflective") { } }; class ReflectivityTag : public XMLTag { public: ReflectivityTag() :XMLTag("reflectivity") { } }; class TransparentTag : public XMLTag { public: TransparentTag() :XMLTag("transparent") { } }; class TransparencyTag : public XMLTag { public: TransparencyTag() :XMLTag("transparency") { } }; class IndexOfRefractionTag : public XMLTag { public: IndexOfRefractionTag() :XMLTag("index_of_refraction") { } }; class LibraryGeometriesTag : public XMLTag { public: LibraryGeometriesTag() :XMLTag("library_geometries") { } }; class GeometryTag : public XMLTag { public: GeometryTag(const QString& id,const QString& name) :XMLTag("geometry") { _attributes.push_back(TagAttribute("id",id)); _attributes.push_back(TagAttribute("name",name)); } }; class MeshTag : public XMLTag { public: MeshTag() :XMLTag("mesh") { } }; class ArraySourceTag : public XMLTag { public: ArraySourceTag(const QString& id,const QString& name) :XMLTag("source") { _attributes.push_back(TagAttribute("id",id)); _attributes.push_back(TagAttribute("name",name)); } }; class FloatArrayTag : public XMLLeafTag { public: enum ARRAYSEMANTIC {VERTPOSITION,VERTNORMAL,VERTCOLOR, FACENORMAL,WEDGETEXCOORD}; template FloatArrayTag(const QString& id,const int count,const MESHTYPE& m,ARRAYSEMANTIC sem,const unsigned int componenttype) :XMLLeafTag("float_array") { _attributes.push_back(TagAttribute("id",id)); _attributes.push_back(TagAttribute("count",QString::number(count))); if ((sem == VERTPOSITION) || (sem == VERTNORMAL) || (sem == VERTCOLOR)) { for(typename MESHTYPE::ConstVertexIterator vit = m.vert.begin();vit != m.vert.end();++vit) { for(unsigned int ii = 0; ii < componenttype;++ii) { if (sem == VERTPOSITION) _text.push_back(QString::number(vit->P()[ii])); else if (sem == VERTCOLOR) _text.push_back(QString::number((vit->C()[ii])/255.0)); else { typename MESHTYPE::VertexType::NormalType r = vit->cN(); r.Normalize(); _text.push_back(QString::number(r[ii])); } } } } else { for(typename MESHTYPE::ConstFaceIterator fit = m.face.begin();fit != m.face.end();++fit) { if (sem == FACENORMAL) { for(unsigned int ii = 0; ii < componenttype;++ii) { typename MESHTYPE::FaceType::NormalType r = fit->cN(); r.Normalize(); _text.push_back(QString::number(r[ii])); } } else { for(unsigned int ii = 0; ii < 3;++ii) { _text.push_back(QString::number(fit->cWT(ii).U())); _text.push_back(QString::number(fit->cWT(ii).V())); } } } } } }; //class FloatWedgeArrayTag : public XMLLeafTag //{ //public: // template // FloatWedgeArrayTag(const QString& id,const int count,const MESHTYPE& m,const AccessorComponentNumberInfo& accessor) // :XMLLeafTag("float_array") // { // _attributes.push_back(TagAttribute("id",id)); // _attributes.push_back(TagAttribute("count",QString::number(count))); // for(typename SIMPLEXACCESSOR::ConstIterator it= accessor._a.begin();it != accessor._a.end(); ++it) // { // for(unsigned int ii = 0; ii < 3;++ii) // { // _text.push_back(QString::number(accessor._a(*it,ii).U())); // _text.push_back(QString::number(accessor._a(*it,ii).V())); // } // } // } //}; class AccessorTag : public XMLTag { public: AccessorTag(const int count,const QString& source,const int stride) :XMLTag("accessor") { _attributes.push_back(TagAttribute("count",QString::number(count))); _attributes.push_back(TagAttribute("source",testSharp(source))); _attributes.push_back(TagAttribute("stride",QString::number(stride))); } }; class ParamTag : public XMLTag { public: ParamTag(const QString& name,const QString& type) :XMLTag("param") { _attributes.push_back(TagAttribute("name",name)); _attributes.push_back(TagAttribute("type",type)); } }; class VerticesTag : public XMLTag { public: VerticesTag(const QString& id) :XMLTag("vertices") { _attributes.push_back(TagAttribute("id",id)); } }; class InputTag : public XMLTag { public: InputTag(const QString& semantic,const QString& source) :XMLTag("input") { _attributes.push_back(TagAttribute("semantic",semantic)); _attributes.push_back(TagAttribute("source",testSharp(source))); } InputTag(const int offset,const QString& semantic,const QString& source) :XMLTag("input") { _attributes.push_back(TagAttribute("offset",QString::number(offset))); _attributes.push_back(TagAttribute("semantic",semantic)); _attributes.push_back(TagAttribute("source",testSharp(source))); } }; class TrianglesTag : public XMLTag { public: TrianglesTag(const int count) :XMLTag("triangles") { _attributes.push_back(TagAttribute("count",QString::number(count))); } TrianglesTag(const int count,const QString& material) :XMLTag("triangles") { _attributes.push_back(TagAttribute("count",QString::number(count))); _attributes.push_back(TagAttribute("material",material)); } }; class PTag : public XMLLeafTag { public: template PTag(const MESHTYPE& m,const unsigned int nedge,bool vcol=false, bool norm = false,bool texcoord = false) :XMLLeafTag("p") { int cont = 0; for(typename MESHTYPE::ConstFaceIterator it= m.face.begin();it != m.face.end(); ++it) { for(unsigned int ii = 0; ii < nedge; ++ii) { int dist = vcg::tri::Index(m,it->cV(ii)); _text.push_back(QString::number(dist)); if (vcol) _text.push_back(QString::number(dist)); if (norm) _text.push_back(QString::number(cont)); if (texcoord) _text.push_back(QString::number(cont * nedge + ii)); } ++cont; } } template PTag(const MESHTYPE& m,const unsigned int nedge,QVector& patchfaces,bool vcol = false, bool norm = false,bool texcoord = false) :XMLLeafTag("p") { int cont = 0; for(QVector::iterator it = patchfaces.begin();it != patchfaces .end(); ++it) { for(unsigned int ii = 0; ii < nedge; ++ii) { const typename MESHTYPE::FaceType& f = m.face[*it]; int dist = f.cV(ii) - &(*m.vert.begin()); _text.push_back(QString::number(dist)); if (vcol) _text.push_back(QString::number(dist)); if (norm) _text.push_back(QString::number(*it)); if (texcoord) _text.push_back(QString::number(*it * nedge + ii)); } ++cont; } } }; class LibraryVisualScenesTag : public XMLTag { public: LibraryVisualScenesTag() :XMLTag("library_visual_scenes") { } }; class VisualSceneTag : public XMLTag { public: VisualSceneTag(const QString& id,const QString& name) :XMLTag("visual_scene") { _attributes.push_back(TagAttribute("id",id)); _attributes.push_back(TagAttribute("name",name)); } }; class NodeTag : public XMLTag { public: NodeTag(const QString& id,const QString& name) :XMLTag("node") { _attributes.push_back(TagAttribute("id",id)); _attributes.push_back(TagAttribute("name",name)); } }; class RotateTag : public XMLLeafTag { public: RotateTag(const QString& sid,const vcg::Point4f& p) :XMLLeafTag("rotate") { _attributes.push_back(TagAttribute("sid",sid)); for(unsigned int ii =0;ii < 4; ++ii) _text.push_back(QString::number(p[ii])); } }; class TranslateTag : public XMLLeafTag { public: TranslateTag(const QString& sid,const vcg::Point4f& p) :XMLLeafTag("translate") { _attributes.push_back(TagAttribute("sid",sid)); for(unsigned int ii =0;ii < 4; ++ii) _text.push_back(QString::number(p[ii])); } }; class InstanceGeometryTag : public XMLTag { public: InstanceGeometryTag(const QString& url) :XMLTag("instance_geometry") { _attributes.push_back(TagAttribute("url",testSharp(url))); } }; class BindMaterialTag : public XMLTag { public: BindMaterialTag() :XMLTag("bind_material") { } }; class InstanceMaterialTag : public XMLTag { public: InstanceMaterialTag(const QString& symbol,const QString& target) :XMLTag("instance_material") { _attributes.push_back(TagAttribute("symbol",symbol)); _attributes.push_back(TagAttribute("target",testSharp(target))); } }; class BindVertexInputTag : public XMLTag { public: BindVertexInputTag(const QString& semantic,const QString& input_semantic,const QString& /*input_set*/) :XMLTag("bind_vertex_input") { _attributes.push_back(TagAttribute("semantic",semantic)); _attributes.push_back(TagAttribute("input_semantic",input_semantic)); } }; class SceneTag : public XMLTag { public: SceneTag() :XMLTag("scene") { } }; class CreatedTag : public XMLLeafTag//added { public: CreatedTag() :XMLLeafTag("created") { QDateTime dateCreated = QDateTime::currentDateTime().toUTC(); QString dateCreatedStr = dateCreated.toString(); _text.push_back(dateCreatedStr); } }; class ModifiedTag : public XMLLeafTag//added { public: ModifiedTag() :XMLLeafTag("modified") { QDateTime dateModified = QDateTime::currentDateTime().toUTC(); QString dateModifiedStr = dateModified.toString(); _text.push_back(dateModifiedStr); } }; class InstanceVisualSceneTag : public XMLTag { public: InstanceVisualSceneTag(const QString& url) :XMLTag("instance_visual_scene") { _attributes.push_back(TagAttribute("url",testSharp(url))); } }; } //Tags class DocumentManager { private: static void connectHierarchyNode(XMLInteriorNode* node0,XMLInteriorNode* node1,XMLLeafNode* leaf) { node1->_sons.push_back(leaf); node0->_sons.push_back(node1); } static void connectHierarchyNode(XMLInteriorNode* node0,XMLInteriorNode* node1,XMLInteriorNode* node2,XMLInteriorNode* node3,XMLNode* node4) { node3->_sons.push_back(node4); node2->_sons.push_back(node3); node1->_sons.push_back(node2); node0->_sons.push_back(node1); } static void connectHierarchyNode(XMLInteriorNode* node0,XMLInteriorNode* node1,XMLInteriorNode* node2,XMLInteriorNode* node3) { node2->_sons.push_back(node3); node1->_sons.push_back(node2); node0->_sons.push_back(node1); } static void connectHierarchyNode(XMLInteriorNode* node0,XMLInteriorNode* node1,XMLInteriorNode* node2) { node1->_sons.push_back(node2); node0->_sons.push_back(node1); } template static void splitMeshInTexturedPatches(const MESHMODELTYPE& m,QVector >& patches) { patches.resize(m.textures.size()); int cc = 0; for(typename MESHMODELTYPE::ConstFaceIterator itf = m.face.begin();itf != m.face.end();++itf) { int tmp = itf->cWT(0).N(); assert(tmp>=0 && tmp static XMLDocument* createColladaDocument(const MESHMODELTYPE& m,const int mask) { //for now we export only triangularface const unsigned int edgefacenum = 3; typedef XMLInteriorNode XNode; typedef XMLLeafNode XLeaf; XNode* root = new XNode(new Tags::ColladaTag()); XNode* assetnode = new XNode(new Tags::AssetTag()); XNode* contributornode = new XNode(new Tags::ContributorTag()); contributornode->_sons.push_back(new XLeaf(new Tags::AuthorTag())); contributornode->_sons.push_back(new XLeaf(new Tags::AuthoringToolTag())); assetnode->_sons.push_back(contributornode); assetnode->_sons.push_back(new XLeaf(new Tags::CreatedTag()));//added assetnode->_sons.push_back(new XLeaf(new Tags::ModifiedTag())); assetnode->_sons.push_back(new XLeaf(new Tags::UpAxisTag())); root->_sons.push_back(assetnode); XNode* libimages = NULL; for(unsigned int ii = 0;ii < m.textures.size();++ii) { if ( ii == 0) libimages = new XNode(new Tags::LibraryImagesTag()); QString subfix = QString::number(ii); XNode* imagenode = new XNode(new Tags::ImageTag(QString("texture") + subfix,QString("texture") + subfix)); XLeaf* initfromnode = new XLeaf(new Tags::InitFromTag(QString::fromStdString(m.textures[ii]))); imagenode->_sons.push_back(initfromnode); libimages->_sons.push_back(imagenode); if (ii == 0) root->_sons.push_back(libimages); } XNode* libmaterials = NULL; for(unsigned int ii = 0;ii < m.textures.size();++ii) { if ( ii == 0) libmaterials = new XNode(new Tags::LibraryMaterialsTag()); QString subfix = QString::number(ii); QString mat = "material" + subfix; XNode* materialnode = new XNode(new Tags::MaterialTag(mat,mat)); XLeaf* instanceeff = new XLeaf(new Tags::InstanceEffectTag(mat+"-fx")); materialnode->_sons.push_back(instanceeff); libmaterials->_sons.push_back(materialnode); if ( ii == 0) root->_sons.push_back(libmaterials); } XNode* libeffects = NULL; for(unsigned int ii = 0;ii < m.textures.size();++ii) { if ( ii == 0) libeffects = new XNode(new Tags::LibraryEffectsTag()); QString subfix = QString::number(ii); QString mat = "material" + subfix + "-fx"; XNode* effectnode = new XNode(new Tags::EffectTag(mat)); XNode* procommnode = new XNode(new Tags::ProfileCommonTag()); QString tex = QString("texture")+subfix; XNode* newparamnode = new XNode(new Tags::NewParamTag(tex+"-surface")); XNode* surfacenode = new XNode(new Tags::SurfaceTag()); XLeaf* initfromnode = new XLeaf(new Tags::InitFromTag(tex)); QImage img(QString::fromStdString(m.textures[ii])); QImage::Format f = img.format(); QString form = "R8G8B8"; if (f==QImage::Format_ARGB32) form = "A8R8G8B8"; XLeaf* formatnode = new XLeaf(new Tags::FormatTag(form)); surfacenode->_sons.push_back(initfromnode); surfacenode->_sons.push_back(formatnode); newparamnode->_sons.push_back(surfacenode); procommnode->_sons.push_back(newparamnode); XNode* newparamnode2 = new XNode(new Tags::NewParamTag(tex+"-sampler")); XNode* samplernode = new XNode(new Tags::Sampler2DTag()); XLeaf* sourcenode = new XLeaf(new Tags::SourceTag(tex+"-surface")); XLeaf* minfilt = new XLeaf(new Tags::MinFilterTag("LINEAR")); XLeaf* magfilt = new XLeaf(new Tags::MagFilterTag("LINEAR")); samplernode->_sons.push_back(sourcenode); samplernode->_sons.push_back(minfilt); samplernode->_sons.push_back(magfilt); newparamnode2->_sons.push_back(samplernode); procommnode->_sons.push_back(newparamnode2); XNode* technode = new XNode(new Tags::TechniqueTag("common")); XNode* blinnnode = new XNode(new Tags::BlinnTag()); XNode* diffusenode = new XNode(new Tags::DiffuseTag()); XLeaf* texturenode = new XLeaf(new Tags::TextureTag(tex+"-sampler","UVSET0")); connectHierarchyNode(blinnnode,diffusenode,texturenode); connectHierarchyNode(procommnode,technode,blinnnode); effectnode->_sons.push_back(procommnode); libeffects->_sons.push_back(effectnode); if ( ii == 0) root->_sons.push_back(libeffects); } XNode* libgeo = new XNode(new Tags::LibraryGeometriesTag()); QString subfix = "0"; QString shape = "shape" + subfix; XNode* geometrynode = new XNode(new Tags::GeometryTag(shape+"-lib",shape)); XNode* meshnode = new XNode(new Tags::MeshTag()); XNode* sourcepos = new XNode(new Tags::SourceTag(shape+"-lib-positions","position")); //AccessorComponentNumberInfo> acc(m); unsigned int return_component_number = CoordNumber::coord(); XLeaf* floatarr = new XLeaf(new Tags::FloatArrayTag(shape+"-lib-positions-array",m.vert.size() * return_component_number,m,Tags::FloatArrayTag::VERTPOSITION,return_component_number)); XNode* techcommnode = new XNode(new Tags::TechniqueCommonTag()); XNode* accessornode = new XNode(new Tags::AccessorTag(m.vert.size(),shape+"-lib-positions-array",return_component_number)); XNode* paramx = new XNode(new Tags::ParamTag("X","float")); XNode* paramy = new XNode(new Tags::ParamTag("Y","float")); XNode* paramz = new XNode(new Tags::ParamTag("Z","float")); sourcepos->_sons.push_back(floatarr); accessornode->_sons.push_back(paramx); accessornode->_sons.push_back(paramy); accessornode->_sons.push_back(paramz); techcommnode->_sons.push_back(accessornode); sourcepos->_sons.push_back(techcommnode); meshnode->_sons.push_back(sourcepos); //CHANGE THIS PIECE OF CODE! bool normalmask = bool((mask & vcg::tri::io::Mask::IOM_FACENORMAL) || (mask & vcg::tri::io::Mask::IOM_WEDGNORMAL) || (mask & vcg::tri::io::Mask::IOM_VERTNORMAL)); if (normalmask) { XNode* sourcenormal = new XNode(new Tags::SourceTag(shape+"-lib-normals","normal")); //we export only triangular face XLeaf* floatnormarr = new XLeaf(new Tags::FloatArrayTag(shape+"-lib-normals-array",m.face.size() * return_component_number,m,Tags::FloatArrayTag::FACENORMAL,return_component_number)); XNode* techcommnormnode = new XNode(new Tags::TechniqueCommonTag()); XNode* accessornormnode = new XNode(new Tags::AccessorTag(m.face.size(),shape+"-lib-normals-array",return_component_number)); //I have to make up the following piece of code XNode* paramnormx = new XNode(new Tags::ParamTag("X","float")); XNode* paramnormy = new XNode(new Tags::ParamTag("Y","float")); XNode* paramnormz = new XNode(new Tags::ParamTag("Z","float")); sourcenormal->_sons.push_back(floatnormarr); accessornormnode->_sons.push_back(paramnormx); accessornormnode->_sons.push_back(paramnormy); accessornormnode->_sons.push_back(paramnormz); techcommnormnode->_sons.push_back(accessornormnode); sourcenormal->_sons.push_back(techcommnormnode); meshnode->_sons.push_back(sourcenormal); } //CHANGE THIS PIECE OF CODE! bool vcolormask = bool((mask & vcg::tri::io::Mask::IOM_VERTCOLOR)); if (vcolormask) { unsigned int color_component_number = 4; XNode* sourcevcolor = new XNode(new Tags::SourceTag(shape+"-lib-vcolor","vcolor")); //we export only triangular face XLeaf* floatvcolorarr = new XLeaf(new Tags::FloatArrayTag(shape+"-lib-vcolor-array",m.vert.size() * color_component_number,m,Tags::FloatArrayTag::VERTCOLOR,color_component_number)); XNode* techcommvcolornode = new XNode(new Tags::TechniqueCommonTag()); XNode* accessorvcolornode = new XNode(new Tags::AccessorTag(m.vert.size(),shape+"-lib-vcolor-array",color_component_number)); //I have to make up the following piece of code XNode* paramvcolorx = new XNode(new Tags::ParamTag("R","float")); XNode* paramvcolory = new XNode(new Tags::ParamTag("G","float")); XNode* paramvcolorz = new XNode(new Tags::ParamTag("B","float")); XNode* paramvcolora = new XNode(new Tags::ParamTag("A","float")); sourcevcolor->_sons.push_back(floatvcolorarr); accessorvcolornode->_sons.push_back(paramvcolorx); accessorvcolornode->_sons.push_back(paramvcolory); accessorvcolornode->_sons.push_back(paramvcolorz); accessorvcolornode->_sons.push_back(paramvcolora); techcommvcolornode->_sons.push_back(accessorvcolornode); sourcevcolor->_sons.push_back(techcommvcolornode); meshnode->_sons.push_back(sourcevcolor); } bool texmask = bool(mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD); if (texmask) { XNode* sourcewedge = new XNode(new Tags::SourceTag(shape+"-lib-map","map")); return_component_number = CoordNumber::coord(); //we export only triangular face XLeaf* floatwedgearr = new XLeaf(new Tags::FloatArrayTag(shape+"-lib-map-array",m.face.size() * return_component_number * edgefacenum,m,Tags::FloatArrayTag::WEDGETEXCOORD,return_component_number)); XNode* techcommwedgenode = new XNode(new Tags::TechniqueCommonTag()); XNode* accessorwedgenode = new XNode(new Tags::AccessorTag(m.face.size() * edgefacenum,shape+"-lib-map-array",return_component_number)); //I have to make up the following piece of code XNode* paramwedgeu = new XNode(new Tags::ParamTag("U","float")); XNode* paramwedgev = new XNode(new Tags::ParamTag("V","float")); sourcewedge->_sons.push_back(floatwedgearr); accessorwedgenode->_sons.push_back(paramwedgeu); accessorwedgenode->_sons.push_back(paramwedgev); techcommwedgenode->_sons.push_back(accessorwedgenode); sourcewedge->_sons.push_back(techcommwedgenode); meshnode->_sons.push_back(sourcewedge); } XNode* vertnode = new XNode(new Tags::VerticesTag(shape+"-lib-vertices")); XNode* inputposnode = new XNode(new Tags::InputTag("POSITION",shape+"-lib-positions")); vertnode->_sons.push_back(inputposnode); //XNode* inputvcolnode = new XNode(new Tags::InputTag("COLOR",shape+"-lib-vcolor")); //vertnode->_sons.push_back(inputvcolnode); meshnode->_sons.push_back(vertnode); XNode* trianglesnode = NULL; //if ((m.textures.size() == 0) || (!texmask)) //{ // //there isn't any texture file // trianglesnode = new XNode(new Tags::TrianglesTag(m.face.size())); //} //else //{ // std::vector> _mytripatches(m.textures.size()); // if ((texmask) && (m.textures.size() > 1)) // { // //there are many textures files - I have to split the mesh in triangular patches that share the same texture's file. // for(MESHMODELTYPE::ConstFaceIterator itf = m.face.begin();itf != m.face.end();++itf) // { // // } // trianglesnode = new XNode(new Tags::TrianglesTag(m.face.size(),"instancematerial")); //} QVector > mytripatches; if ((texmask) && (m.textures.size() != 0)) splitMeshInTexturedPatches(m,mytripatches); QVector >::iterator itp = mytripatches.begin(); int indmat = 0; do { if ((m.textures.size() == 0) || (!texmask)) { //there isn't any texture file trianglesnode = new XNode(new Tags::TrianglesTag(m.face.size())); } else trianglesnode = new XNode(new Tags::TrianglesTag(mytripatches[indmat].size(),"material" + QString::number(indmat))); XNode* inputtrinode = new XNode(new Tags::InputTag(0,"VERTEX",shape+"-lib-vertices")); trianglesnode->_sons.push_back(inputtrinode); int offs=1; if (vcolormask) { XNode* inputvcolnode = new XNode(new Tags::InputTag(offs,"COLOR",shape+"-lib-vcolor")); trianglesnode->_sons.push_back(inputvcolnode); ++offs; } if (normalmask) { XNode* inputnormnode = new XNode(new Tags::InputTag(offs,"NORMAL",shape+"-lib-normals")); trianglesnode->_sons.push_back(inputnormnode); ++offs; } if (texmask) { XNode* inputwedgenode = new XNode(new Tags::InputTag(offs,"TEXCOORD",shape+"-lib-map")); trianglesnode->_sons.push_back(inputwedgenode); offs++; } XLeaf* polyleaf = NULL; if (itp == mytripatches.end()) polyleaf = new XLeaf(new Tags::PTag(m,edgefacenum,vcolormask,normalmask,texmask)); else polyleaf = new XLeaf(new Tags::PTag(m,edgefacenum,(*itp),vcolormask,normalmask,texmask)); trianglesnode->_sons.push_back(polyleaf); meshnode->_sons.push_back(trianglesnode); ++indmat; if (itp != mytripatches.end()) ++itp; }while(itp != mytripatches.end()); connectHierarchyNode(libgeo,geometrynode,meshnode); root->_sons.push_back(libgeo); XNode* libvisualnode = new XNode(new Tags::LibraryVisualScenesTag()); XNode* visualscenenode = new XNode(new Tags::VisualSceneTag("VisualSceneNode","VisualScene")); XNode* nodenode = new XNode(new Tags::NodeTag("node","node")); XNode* instgeonode = new XNode(new Tags::InstanceGeometryTag(shape+"-lib")); if (m.textures.size() > 0) { XNode* bindnode = new XNode(new Tags::BindMaterialTag()); XNode* techcommmatnode = new XNode(new Tags::TechniqueCommonTag()); for(unsigned int ii = 0; ii < m.textures.size(); ++ii) { XNode* instmatnode = new XNode(new Tags::InstanceMaterialTag("material" + QString::number(ii),"material" + QString::number(ii))); XNode* bindvertnode = new XNode(new Tags::BindVertexInputTag("UVSET0","TEXCOORD","0")); connectHierarchyNode(techcommmatnode,instmatnode,bindvertnode); } connectHierarchyNode(visualscenenode,nodenode,instgeonode,bindnode,techcommmatnode); } else connectHierarchyNode(visualscenenode,nodenode,instgeonode); libvisualnode->_sons.push_back(visualscenenode); root->_sons.push_back(libvisualnode); XNode* scenenode = new XNode(new Tags::SceneTag()); XNode* instvisualscenenode = new XNode(new Tags::InstanceVisualSceneTag("VisualSceneNode")); scenenode->_sons.push_back(instvisualscenenode); root->_sons.push_back(scenenode); return new XMLDocument(root); } static void destroyColladaDocument(XMLDocument* doc) { delete doc; } //template //static int importColladaDocument(const QDomDocument& doc,MESHMODELTYPE& m,const int mask) //{ // QDomElement root = doc.toElement(); // if (root.isNull()) // return UtilDAE::E_BAD_CONVERTION_FROM_NODE_TO_ELEMENT; // QDomNodeList lst = root.elementsByTagName("COLLADA"); // int err = UtilDAE::checkOccurencies(lst,UtilDAE::ONE); // if ( // return vcg::tri::io::UtilDAE::E_NOERROR; //} }; } //Collada #endif