vcglib/wrap/dae/colladaformat.h

1203 lines
32 KiB
C++

/****************************************************************************
* 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 <wrap/dae/xmldocumentmanaging.h>
#include <vcg/space/point4.h>
#include <vcg/space/color4.h>
#include <QtGui/QImage>
#include <QtCore/QVector>
#include <QDateTime>
template<typename POINTTYPE>
struct CoordNumber{public: static unsigned int coord() { return 0; }};
template<> struct CoordNumber<vcg::Point2f> { public: static unsigned int coord() { return 2; } };
template<> struct CoordNumber<vcg::Point3f> { public: static unsigned int coord() { return 3; } };
template<> struct CoordNumber<vcg::Point4f> { public: static unsigned int coord() { return 4; } };
template<> struct CoordNumber<vcg::Color4b> { 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<typename MESHTYPE>
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<typename MESHTYPE,typename SIMPLEXACCESSOR>
// FloatWedgeArrayTag(const QString& id,const int count,const MESHTYPE& m,const AccessorComponentNumberInfo<MESHTYPE,SIMPLEXACCESSOR>& 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<typename MESHTYPE>
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<typename MESHTYPE>
PTag(const MESHTYPE& m,const unsigned int nedge,QVector<int>& patchfaces,bool vcol = false, bool norm = false,bool texcoord = false)
:XMLLeafTag("p")
{
int cont = 0;
for(QVector<int>::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<typename MESHMODELTYPE>
static void splitMeshInTexturedPatches(const MESHMODELTYPE& m,QVector<QVector<int> >& 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<patches.size());
patches[tmp].push_back(cc);
++cc;
}
}
public:
template<typename MESHMODELTYPE>
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<MESHMODELTYPE,MeshAccessors::VertexPositionAccessor<const MESHMODELTYPE>> acc(m);
unsigned int return_component_number = CoordNumber<typename MESHMODELTYPE::CoordType>::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<typename MESHMODELTYPE::FaceType::TexCoordType::PointType>::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<std::vector<int>> _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<QVector<int> > mytripatches;
if ((texmask) && (m.textures.size() != 0))
splitMeshInTexturedPatches(m,mytripatches);
QVector<QVector<int> >::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<typename MESHMODELTYPE>
//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