You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1202 lines
33 KiB
1202 lines
33 KiB
/**************************************************************************** |
|
* 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<typename Scalar> struct CoordNumber<vcg::Point2<Scalar>> { public: static unsigned int coord() { return 2; } }; |
|
template<typename Scalar> struct CoordNumber<vcg::Point3<Scalar>> { public: static unsigned int coord() { return 3; } }; |
|
template<typename Scalar> struct CoordNumber<vcg::Point4<Scalar>> { 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
|
|
|