diff --git a/wrap/dae/colladaformat.h b/wrap/dae/colladaformat.h new file mode 100644 index 00000000..bfabaf31 --- /dev/null +++ b/wrap/dae/colladaformat.h @@ -0,0 +1,1001 @@ +#ifndef _COLLADA_FORMAT_H +#define _COLLADA_FORMAT_H + +#include +#include +#include +#include + +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 TrasparentTag : public XMLTag + { + public: + TrasparentTag() + :XMLTag("trasparent") + { + } + }; + + class TrasparencyTag : public XMLTag + { + public: + TrasparencyTag() + :XMLTag("trasparency") + { + } + }; + + 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: + template + FloatArrayTag(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 < accessor._return_value_component_number;++ii) + _text.push_back(QString::number(accessor._a(*it)[ii])); + } + } + }; + + 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,const QString& material) + :XMLTag("triangles") + { + _attributes.push_back(TagAttribute("count",QString::number(count))); + _attributes.push_back(TagAttribute("semantic",material)); + } + }; + + class PTag : public XMLLeafTag + { + public: + template + PTag(const MESHTYPE& m,const unsigned int nedge,bool norm = false,bool texcoord = false) + :XMLLeafTag("p") + { + int cont = 0; + for(MESHTYPE::ConstFaceIterator it= m.face.begin();it != m.face.end(); ++it) + { + for(unsigned int ii = 0; ii < nedge; ++ii) + { + int dist = it->V(ii) - &(*m.vert.begin()); + _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 POLYGONACCESSOR1>& p1,const AccessorInfo& p2) + :XMLLeafTag("p") + { + for(MESHTYPE::ConstFaceIterator it= m.face.begin();it != m.face.end(); ++it) + { + for(const unsigned int ii = 0; ii < p1._return_value_component_number;++ii) + { + _text.push_back(QSTring::number(p1._a(*it)[ii]); + + } + } + } + + template + PTag(const MESHTYPE& m,const AccessorInfo& p1) + :XMLLeafTag("p") + { + for(MESHTYPE::ConstFaceIterator it= m.face.begin();it != m.face.end(); ++it) + { + for(const unsigned int ii = 0; ii < p1._return_value_component_number;++ii) + _text.push_back(QSTring::number(p1._a(*it)[ii]); + } + } + + template + PTag(const MESHTYPE& m,const AccessorInfo& p1) + :XMLLeafTag("p") + { + for(MESHTYPE::ConstFaceIterator it= m.face.begin();it != m.face.end(); ++it) + { + for(const unsigned int ii = 0; ii < p1._return_value_component_number;++ii) + _text.push_back(QSTring::number(p1._a(*it)[ii]); + } + }*/ + }; + + 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)); + _attributes.push_back(TagAttribute("target",input_set)); + } + }; + + class SceneTag : public XMLTag + { + public: + SceneTag() + :XMLTag("scene") + { + } + }; + + 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); + } + +public: + template + 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::UpAxisTag())); + root->_sons.push_back(assetnode); + + XNode* libimages = new XNode(new Tags::LibraryImagesTag()); + for(unsigned int ii = 0;ii < m.textures.size();++ii) + { + 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); + } + root->_sons.push_back(libimages); + + XNode* libmaterials = new XNode(new Tags::LibraryMaterialsTag()); + for(unsigned int ii = 0;ii < m.textures.size();++ii) + { + 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); + } + root->_sons.push_back(libmaterials); + + XNode* libeffects = new XNode(new Tags::LibraryEffectsTag()); + for(unsigned int ii = 0;ii < m.textures.size();++ii) + { + 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* emissionnode = new XNode(new Tags::EmissionTag()); + XLeaf* colorem = new XLeaf(new Tags::ColorTag(0,0,0,1)); + XNode* ambientnode = new XNode(new Tags::AmbientTag()); + XLeaf* coloramb = new XLeaf(new Tags::ColorTag(0,0,0,1)); + XNode* diffusenode = new XNode(new Tags::DiffuseTag()); + XLeaf* texturenode = new XLeaf(new Tags::TextureTag(tex,"UVSET0")); + XNode* specularnode = new XNode(new Tags::SpecularTag()); + XLeaf* colorspec = new XLeaf(new Tags::ColorTag(0,0,0,1)); + XNode* shinenode = new XNode(new Tags::ShininessTag()); + XLeaf* floatshine = new XLeaf(new Tags::FloatTag(0.3)); + XNode* reflectivenode = new XNode(new Tags::ReflectiveTag()); + XLeaf* colorref = new XLeaf(new Tags::ColorTag(0,0,0,1)); + XNode* reflectivitynode = new XNode(new Tags::ReflectivityTag()); + XLeaf* floatrefl = new XLeaf(new Tags::FloatTag(0.5)); + XNode* transparentnode = new XNode(new Tags::TrasparentTag()); + XLeaf* colortra = new XLeaf(new Tags::ColorTag(0,0,0,1)); + XNode* transparencynode = new XNode(new Tags::TrasparencyTag()); + XLeaf* floattra = new XLeaf(new Tags::FloatTag(0.0)); + XNode* refranode = new XNode(new Tags::IndexOfRefractionTag()); + XLeaf* floatrefrac = new XLeaf(new Tags::FloatTag(0.0)); + + connectHierarchyNode(blinnnode,emissionnode,colorem); + connectHierarchyNode(blinnnode,ambientnode,coloramb); + connectHierarchyNode(blinnnode,diffusenode,texturenode); + connectHierarchyNode(blinnnode,specularnode,colorspec); + connectHierarchyNode(blinnnode,shinenode,floatshine); + connectHierarchyNode(blinnnode,reflectivenode,colorref); + connectHierarchyNode(blinnnode,reflectivitynode,floatrefl); + connectHierarchyNode(blinnnode,transparentnode,colortra); + connectHierarchyNode(blinnnode,transparencynode,floattra); + connectHierarchyNode(blinnnode,refranode,floatrefrac); + + connectHierarchyNode(procommnode,technode,blinnnode); + + effectnode->_sons.push_back(procommnode); + libeffects->_sons.push_back(effectnode); + } + 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); + acc._return_value_component_number = CoordNumber::coord(); + XLeaf* floatarr = new XLeaf(new Tags::FloatArrayTag(shape+"-lib-positions-array",m.vert.size() * CoordNumber::coord(),m,acc)); + XNode* techcommnode = new XNode(new Tags::TechniqueCommonTag()); + XNode* accessornode = new XNode(new Tags::AccessorTag(m.vert.size(),shape+"-lib-positions-array",acc._return_value_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")); + AccessorComponentNumberInfo> pnacc(m); + pnacc._return_value_component_number = CoordNumber::coord(); + //we export only triangular face + XLeaf* floatnormarr = new XLeaf(new Tags::FloatArrayTag(shape+"-lib-normals-array",m.face.size() * pnacc._return_value_component_number,m,pnacc)); + XNode* techcommnormnode = new XNode(new Tags::TechniqueCommonTag()); + XNode* accessornormnode = new XNode(new Tags::AccessorTag(m.face.size(),shape+"-lib-normals-array",acc._return_value_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); + } + + bool texmask = bool(mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD); + if (texmask) + { + XNode* sourcewedge = new XNode(new Tags::SourceTag(shape+"-lib-map","map")); + AccessorComponentNumberInfo> pwacc(m); + pwacc._return_value_component_number = CoordNumber::coord();; + //we export only triangular face + XLeaf* floatwedgearr = new XLeaf(new Tags::FloatWedgeArrayTag(shape+"-lib-map-array",m.face.size() * pwacc._return_value_component_number * edgefacenum,m,pwacc)); + XNode* techcommwedgenode = new XNode(new Tags::TechniqueCommonTag()); + XNode* accessorwedgenode = new XNode(new Tags::AccessorTag(m.face.size() * edgefacenum,shape+"-lib-map-array",pwacc._return_value_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); + meshnode->_sons.push_back(vertnode); + XNode* trianglesnode = new XNode(new Tags::TrianglesTag(m.face.size(),"instancematerial")); + XNode* inputtrinode = new XNode(new Tags::InputTag(0,"VERTEX",shape+"-lib-vertices")); + trianglesnode->_sons.push_back(inputtrinode); + if (normalmask) + { + XNode* inputnormnode = new XNode(new Tags::InputTag(1,"NORMAL",shape+"-lib-normals")); + trianglesnode->_sons.push_back(inputnormnode); + } + + if (texmask) + { + XNode* inputwedgenode = new XNode(new Tags::InputTag(2,"TEXCOORD",shape+"-lib-map")); + trianglesnode->_sons.push_back(inputwedgenode); + } + + XLeaf* polyleaf = new XLeaf(new Tags::PTag(m,edgefacenum,normalmask,texmask)); + + trianglesnode->_sons.push_back(polyleaf); + meshnode->_sons.push_back(trianglesnode); + + 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")); + XNode* bindnode = new XNode(new Tags::BindMaterialTag()); + XNode* techcommmatnode = new XNode(new Tags::TechniqueCommonTag()); + XNode* instmatnode = new XNode(new Tags::InstanceMaterialTag("instancematerial","material0")); + XNode* bindvertnode = new XNode(new Tags::BindVertexInputTag("UVSET0","TEXCOORD","0")); + connectHierarchyNode(instgeonode,bindnode,techcommmatnode,instmatnode,bindvertnode); + 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; + } +}; +} //Collada +#endif \ No newline at end of file diff --git a/wrap/dae/meshaccessors.h b/wrap/dae/meshaccessors.h new file mode 100644 index 00000000..c4fd927c --- /dev/null +++ b/wrap/dae/meshaccessors.h @@ -0,0 +1,254 @@ +#ifndef _MESH_ACCESSORS_H +#define _MESH_ACCESSORS_H + + +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; + } +}; + + + + +namespace MeshAccessors +{ +template +class VertexAccessor +{ +public: + typedef typename MESHTYPE::ConstVertexIterator ConstIterator; + typedef typename MESHTYPE::VertexIterator Iterator; + + VertexAccessor(MESHTYPE& m) + :_m(m) + { + + } + + ConstIterator begin() const + { + return _m.vert.begin(); + } + + ConstIterator end() const + { + return _m.vert.end(); + } + + Iterator begin() + { + return _m.vert.begin(); + } + + Iterator end() + { + return _m.vert.end(); + } + + MESHTYPE& _m; +}; + +template +class VertexPositionAccessor : public VertexAccessor +{ +public: + VertexPositionAccessor(MESHTYPE& m) + :VertexAccessor(m) + { + } + + template + typename const VERTEXTYPE::CoordType operator()(VERTEXTYPE& v) const + { + return v.P(); + } +}; + +template +class VertexNormalAccessor : public VertexAccessor +{ +public: + VertexNormalAccessor(MESHTYPE& m) + :VertexAccessor(m) + { + } + + template + typename const VERTEXTYPE::NormalType operator()(VERTEXTYPE& v) const + { + return v.N(); + } +}; + +template +class VertexTextureCoordinateAccessor : public VertexAccessor +{ +public: + VertexTextureCoordinateAccessor(MESHTYPE& m) + :VertexAccessor(m) + { + } + + template + typename const VERTEXTYPE::TexCoordType operator()(VERTEXTYPE& v) const + { + return v.T(); + } +}; + +template +class PolygonAccessor +{ +public: + typedef typename MESHTYPE::ConstFaceIterator ConstIterator; + typedef typename MESHTYPE::FaceIterator Iterator; + + PolygonAccessor(MESHTYPE& m) + :_m(m) + { + + } + + ConstIterator begin() const + { + return _m.face.begin(); + } + + ConstIterator end() const + { + return _m.face.end(); + } + + Iterator begin() + { + return _m.face.begin(); + } + + Iterator end() + { + return _m.face.end(); + } + + MESHTYPE& _m; +}; + +template +class PolygonPositionAccessor : public PolygonAccessor +{ +public: + PolygonPositionAccessor(MESHTYPE& m) + :PolygonAccessor(m) + { + } + + template + typename const POLYGONTYPE::CoordType operator()(POLYGONTYPE& p,const unsigned int index) const + { + return p.V(i)->P(); + } +}; + +template +class PolygonNormalAccessor : public PolygonAccessor +{ +public: + PolygonNormalAccessor(MESHTYPE& m) + :PolygonAccessor(m) + { + } + + template + typename const POLYGONTYPE::NormalType operator()(const POLYGONTYPE& p) const + { + POLYGONTYPE::NormalType r = p.cN(); + return r.Normalize(); + } +}; + +template +class PolygonWedgeTextureCoordinateAccessor : public PolygonAccessor +{ +public: + template + typename const POLYGONTYPE::TexCoordType operator()(POLYGONTYPE& p,const unsigned int index) const + { + return p.cWT(index); + } + + PolygonWedgeTextureCoordinateAccessor(MESHTYPE& m) + :PolygonAccessor(m) + { + } +}; +} //MeshAccessors + +template +struct AccessorInfo +{ + AccessorInfo(const MESHTYPE& m) + :_a(m) + { + + } + + ACCESSOR _a; +}; + +template +struct AccessorComponentNumberInfo : public AccessorInfo +{ + AccessorComponentNumberInfo(const MESHTYPE& m) + :AccessorInfo(m) + { + } + + unsigned int _return_value_component_number; +}; + +template +struct AccessorPolygonEdgeNumberInfo : public AccessorInfo +{ + AccessorPolygonEdgeNumberInfo(const MESHTYPE& m) + :AccessorInfo(m) + { + } + + unsigned int _edge_number; +}; + +#endif \ No newline at end of file diff --git a/wrap/dae/util_dae.h b/wrap/dae/util_dae.h new file mode 100644 index 00000000..0a7c338b --- /dev/null +++ b/wrap/dae/util_dae.h @@ -0,0 +1,530 @@ +#ifndef __VCGLIB_UTILDAE +#define __VCGLIB_UTILDAE + + + +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +namespace vcg { +namespace tri { +namespace io { + class InfoDAE + { + public: + + InfoDAE() + { + doc = NULL; + } + + ~InfoDAE() + { + delete doc; + } + + QDomDocument* doc; + }; + + class AdditionalInfoDAE : public AdditionalInfo + { + public: + vcg::tri::io::InfoDAE* dae; + std::vector texturefile; + + AdditionalInfoDAE() + :AdditionalInfo() + { + mask = 0; + numvert = 0; + numface = 0; + } + + ~AdditionalInfoDAE() + { + delete dae; + texturefile.clear(); + } + }; + + class UtilDAE + + { + public: + enum DAEError + { + E_NOERROR, // 0 + E_CANTOPEN, // 1 + E_NOGEOMETRYLIBRARY, // 2 + E_NOMESH, // 3 + E_NOVERTEXPOSITION, // 4 + E_NO3DVERTEXPOSITION, // 5 + E_NO3DSCENE, // 6 + E_INCOMPATIBLECOLLADA141FORMAT, //7 + E_UNREFERENCEBLEDCOLLADAATTRIBUTE, // 8 + E_NOPOLYGONALMESH, //9 + E_CANTSAVE //10 + }; + + + + template + class MyPolygon + { + public: + typedef VERTEX_TYPE BaseVertexType; + + int _nvert; + std::vector _pv; + std::vector< vcg::TexCoord2 > _txc; + + + MyPolygon(int n) + :_nvert(n),_pv(_nvert),_txc(_nvert) + { + } + }; + + template + class PolygonalMesh + { + public: + typedef POLYGONAL_TYPE FaceType; + + enum PERWEDGEATTRIBUTETYPE {NONE = 0,NORMAL = 1,MULTITEXTURECOORD = 2,MULTICOLOR = 4}; + + typedef typename FaceType::BaseVertexType VertexType; + typedef VertexType* VertexPointer; + typedef typename std::vector::iterator VertexIterator; + typedef typename std::vector::iterator PolygonIterator; + + vcg::Box3 bbox; + + std::vector vert; + std::vector _pols; + + void generatePointsVector(std::vector >& v) + { + for(typename PolygonalMesh::PolygonIterator itp = _pols.begin();itp != _pols.end();++itp) + { + v.push_back(std::vector()); + for(typename std::vector::iterator itv = itp->_pv.begin();itv != itp->_pv.end();++itv) + { + v[v.size() - 1].push_back((*itv)->P()); + } + } + } + + void usePerWedgeAttributes(PERWEDGEATTRIBUTETYPE att,const unsigned int multitexture = 1,const unsigned int multicolor = 1) + { + if (att != NONE) + { + for(PolygonIterator itp = _pols.begin();itp != _pols.end();++itp) + { + if (att & MULTICOLOR) itp->usePerWedgeColor(multicolor); + if (att & MULTITEXTURECOORD) itp->usePerWedgeMultiTexture(multitexture); + if (att & NORMAL) itp->usePerWedgeNormal(); + } + } + } + + template + void triangulate(TRIMESH& mesh) + { + std::vector > pl; + mesh.vert.resize(vert.size()); + int multicoor = 0; + //PolygonalMesh's points has been copied in TriangularMesh + for(size_t jj = 0;jj < mesh.vert.size();++jj) + mesh.vert[jj].P() = vert[jj].P(); + + bool texen = mesh.face.IsWedgeTexEnabled(); + unsigned int totaltri = 0; + for(size_t ii = 0;ii < _pols.size();++ii) + totaltri += _pols[ii]._nvert - 2; + + mesh.face.resize(totaltri); + + //transform the polygonal mesh in a vector> + generatePointsVector(pl); + + + int trioff = 0; + //foreach Polygon + for(size_t ii = 0;ii < pl.size();++ii) + { + std::vector tx; + std::vector > pl2(1); + pl2[0] = pl[ii]; + + vcg::glu_tesselator::tesselate(pl2,tx); + size_t ntri = tx.size() / 3; + assert(tx.size() % 3 == 0); + + + int polvert = 0; + //foreach triangle + for(size_t tr = 0;tr < ntri;++tr) + { + + //typename TRIMESH::FaceType& f = mesh.face[tr]; + + //typename TRIMESH::FaceType& f = mesh.face[tr]; + for(unsigned int tt = 0;tt < 3; ++tt) + { + mesh.face[trioff + tr].V(tt) = &(mesh.vert[_pols[ii]._pv[tx[3 * tr + tt]] - &(vert[0])]); + //vcg::Point3f ppp = mesh.face[tr].V(tt)->P(); + if (texen) + { + /* f.WT(multicoor).U() = _pols[ii]._txc[polvert].U(); + f.WT(multicoor).V() = _pols[ii]._txc[polvert].V(); + f.WT(multicoor).N() = _pols[ii]._txc[polvert].N();*/ + + } + polvert = (polvert + 1) % _pols[ii]._nvert; + } + //mesh.face.push_back(f); + } + trioff += ntri; + } + assert(trioff == totaltri); + } + }; + + static const char *ErrorMsg(int error) + { + static const char * dae_error_msg[] = + { + "No errors", + "Can't open file", + "File without a geometry library", + "There isn't mesh in file", + "The meshes in file haven't the vertex position attribute", + "The importer assumes that the OpenMeshType uses a 3D point for the vertex position", + "There isn't any scene in Collada file", + "The input file is not compatible with COLLADA 1.41 standard format", + "Collada file is trying to referece an attribute that is not in the file", + "This version of Collada Importer support only triangular and polygonal mesh file" + }; + + if(error>9 || error<0) return "Unknown error"; + else return dae_error_msg[error]; + }; + protected: + inline static void referenceToANodeAttribute(const QDomNode n,const QString& attr,QString& url_st) + { + url_st = n.toElement().attribute(attr); + int sz = url_st.size() - 1; + url_st = url_st.right(sz); + assert(url_st.size() != 0); + } + + inline static QDomNode findNodeBySpecificAttributeValue(const QDomNodeList& ndl,const QString& attrname,const QString& attrvalue) + { + int ndl_size = ndl.size(); + assert(ndl_size != 0); + int ind = 0; + while(ind < ndl_size) + { + QString st = ndl.at(ind).toElement().attribute(attrname); + if (st == attrvalue) + return ndl.at(ind); + ++ind; + } + return QDomNode(); + } + + inline static QDomNode findNodeBySpecificAttributeValue(const QDomNode n,const QString& tag,const QString& attrname,const QString& attrvalue) + { + return findNodeBySpecificAttributeValue(n.toElement().elementsByTagName(tag),attrname,attrvalue); + } + + inline static QDomNode findNodeBySpecificAttributeValue(const QDomDocument n,const QString& tag,const QString& attrname,const QString& attrvalue) + { + return findNodeBySpecificAttributeValue(n.elementsByTagName(tag),attrname,attrvalue); + } + + inline static bool isThereTag(const QDomNodeList& list) + { + return ((list.size() > 0) ? true : false); + } + + inline static bool isThereTag(const QDomNode n,const QString& tagname) + { + return isThereTag(n.toElement().elementsByTagName(tagname)); + } + + inline static bool isThereTag(const QDomDocument n,const QString& tagname) + { + return isThereTag(n.elementsByTagName(tagname)); + } + + + inline static QDomNode attributeSourcePerSimplex(const QDomNode n,const QDomDocument startpoint,const QString& sem) + { + QDomNodeList vertattr = n.toElement().elementsByTagName("input"); + for(int ind = 0;ind < vertattr.size();++ind) + { + if (vertattr.at(ind).toElement().attribute("semantic") == sem) + { + QString url; + referenceToANodeAttribute(vertattr.at(ind),"source",url); + return findNodeBySpecificAttributeValue(startpoint,"source","id",url); + } + } + return QDomNode(); + } + + inline static void valueStringList(QStringList& res,const QDomNode srcnode,const QString& tag) + { + QDomNodeList list = srcnode.toElement().elementsByTagName(tag); + assert(list.size() == 1); + QString nd = list.at(0).firstChild().nodeValue(); + res = nd.split(" "); + if (res.last() == "") + res.removeLast(); + + } + + /*inline static bool removeChildNode(QDomNodeList*/ + + inline static bool removeChildNodeList(QDomNodeList& nodelst,const QString& tag = "", const QString& attribname = "", const QString& attribvalue = "") + { + for(int jj = 0;jj < nodelst.size();++jj) + { + removeChildNode(nodelst.at(jj),tag,attribname,attribvalue); + } + return true; + } + + + inline static bool removeChildNode(QDomNode node,const QString& tag = "", const QString& attribname = "", const QString& attribvalue = "") + { + QDomNodeList clst = node.childNodes(); + for(int ii = 0;ii < clst.size();++ii) + { + QDomNode oldchild = node.childNodes().at(ii); + if (tag != "") + { + if ((attribname != "") && (attribvalue != "")) + { + if (clst.at(ii).toElement().attribute(attribname) == attribvalue) + node.removeChild(oldchild); + } + else + { + QString nm = clst.at(ii).nodeName(); + if (clst.at(ii).nodeName() == tag) + { + node.removeChild(oldchild); + } + } + } + else node.removeChild(oldchild); + } + return true; + } + + static void ParseRotationMatrix(vcg::Matrix44f& m,const std::vector& t) + { + vcg::Matrix44f tmp; + tmp.SetIdentity(); + for(unsigned int ii = 0;ii < t.size();++ii) + { + QString rt = t[ii].firstChild().nodeValue(); + QStringList rtl = rt.split(" "); + if (rtl.last() == "") rtl.removeLast(); + assert(rtl.size() == 4); + tmp.SetRotate(rtl.at(3).toFloat(),vcg::Point3f(rtl.at(0).toFloat(),rtl.at(1).toFloat(),rtl.at(2).toFloat())); + tmp *= tmp; + } + m = m * tmp; + } + + static void AddTranslation(vcg::Matrix44f& m,const QDomNode t) + { + QDomNode tr = t.firstChild(); + QString coord = tr.nodeValue(); + QStringList coordlist = coord.split(" "); + if (coordlist.last() == "") + coordlist.removeLast(); + assert(coordlist.size() == 3); + m[0][0] = 1.0f; + m[1][1] = 1.0f; + m[2][2] = 1.0f; + m[3][3] = 1.0f; + m[0][3] = coordlist.at(0).toFloat(); + m[1][3] = coordlist.at(1).toFloat(); + m[2][3] = coordlist.at(2).toFloat(); + } + + static void TransfMatrix(const QDomNode parentnode,const QDomNode presentnode,vcg::Matrix44f& m) + { + if (presentnode == parentnode) return; + else + { + QDomNode par = presentnode.parentNode(); + std::vector rotlist; + QDomNode trans; + for(int ch = 0;ch < par.childNodes().size();++ch) + { + if (par.childNodes().at(ch).nodeName() == "rotate") + rotlist.push_back(par.childNodes().at(ch)); + else if (par.childNodes().at(ch).nodeName() == "translate") + { + trans = par.childNodes().at(ch); + } + } + vcg::Matrix44f tmp; + tmp.SetIdentity(); + if (!trans.isNull()) AddTranslation(tmp,trans); + ParseRotationMatrix(tmp,rotlist); + m = m * tmp; + TransfMatrix(parentnode,par,m); + } + } + + inline static int findOffSetForASingleSimplex(QDomNode node) + { + QDomNodeList wedatts = node.toElement().elementsByTagName("input"); + int max = 0; + if (wedatts.size() == 0) return -1; + else + { + for(int ii = 0;ii < wedatts.size();++ii) + { + int tmp = wedatts.at(ii).toElement().attribute("offset").toInt(); + if (tmp > max) max = tmp; + } + } + return max + 1; + } + + inline static int findStringListAttribute(QStringList& list,const QDomNode node,const QDomNode poly,const QDomDocument startpoint,const char* token) + { + int offset; + if (!node.isNull()) + { + offset = node.toElement().attribute("offset").toInt(); + QDomNode st = attributeSourcePerSimplex(poly,startpoint,token); + valueStringList(list,st,"float_array"); + } + return offset; + } + + inline static QDomNode textureFinder(const QString& textname,const QDomDocument doc) + { + //visual_scene -> instance_material + QDomNodeList vis_scn = doc.elementsByTagName("library_visual_scenes"); + if (vis_scn.size() != 1) + return QDomNode(); + QDomNode symb = findNodeBySpecificAttributeValue(vis_scn.at(0),QString("instance_material"),QString("symbol"),textname); + if (symb.isNull()) + return QDomNode(); + QString tar = symb.toElement().attribute("target"); + if (tar.isNull()) + return QDomNode(); + tar = tar.remove('#'); + + //library_material -> material -> instance_effect + QDomNodeList lib_mat = doc.elementsByTagName("library_materials"); + if (lib_mat.size() != 1) + return QDomNode(); + QDomNode material = findNodeBySpecificAttributeValue(lib_mat.at(0),QString("material"),QString("id"),tar); + if (material.isNull()) + return QDomNode(); + QDomNodeList in_eff = material.toElement().elementsByTagName("instance_effect"); + if (vis_scn.size() == 0) + return QDomNode(); + QString url = in_eff.at(0).toElement().attribute("url"); + if ((url.isNull()) || (url == "")) + return QDomNode(); + url = url.remove('#'); + + //library_effects -> effect -> instance_effect + QDomNodeList lib_eff = doc.elementsByTagName("library_effects"); + if (lib_eff.size() != 1) + return QDomNode(); + QDomNode effect = findNodeBySpecificAttributeValue(lib_eff.at(0),QString("effect"),QString("id"),url); + if (effect.isNull()) + return QDomNode(); + QDomNodeList init_from = effect.toElement().elementsByTagName("init_from"); + if (init_from.size() == 0) + return QDomNode(); + QString img_id = init_from.at(0).toElement().text(); + if ((img_id.isNull()) || (img_id == "")) + return QDomNode(); + + //library_images -> image + QDomNodeList lib_img = doc.elementsByTagName("library_images"); + if (lib_img.size() != 1) + return QDomNode(); + QDomNode img = findNodeBySpecificAttributeValue(lib_img.at(0),QString("image"),QString("id"),img_id); + if (img.isNull()) + return QDomNode(); + return img; + } + + static int indexTextureByImgNode(const QDomDocument doc,const QDomNode node) + { + QDomNodeList libim = doc.elementsByTagName(QString("library_images")); + if (libim.size() != 1) + return -1; + QDomNodeList imgs = libim.at(0).toElement().elementsByTagName("image"); + + int ii = 0; + bool found = false; + while((ii < imgs.size()) && (!found)) + { + if (imgs.at(ii) == node) + found = true; + else ++ii; + } + if (found) + return ii; + else + return -1; + } + + struct WedgeAttribute + { + QDomNode wnsrc; + QStringList wn; + int offnm; + + QDomNode wtsrc; + QStringList wt; + int stride; + int offtx; + + QDomNode wcsrc; + QStringList wc; + int offcl; + }; + }; +} +} +} + +#endif diff --git a/wrap/dae/xmldocumentmanaging.cpp b/wrap/dae/xmldocumentmanaging.cpp new file mode 100644 index 00000000..2c9263be --- /dev/null +++ b/wrap/dae/xmldocumentmanaging.cpp @@ -0,0 +1,55 @@ +#include +#include + +XMLNode::XMLNode(XMLTag* tag) +:_tag(tag) +{ +} + +XMLNode::~XMLNode() +{ + delete _tag; +} + +XMLLeafNode::XMLLeafNode(XMLLeafTag* leaftag) +:XMLNode(leaftag) +{ +} + +XMLLeafNode::~XMLLeafNode() +{ + +} + + +void XMLLeafNode::applyProcedure(Visitor& v) +{ + v(*this); +} + +XMLInteriorNode::XMLInteriorNode(XMLTag* tag) +:XMLNode(tag) +{ +} + +XMLNode* XMLInteriorNode::son(int ii) +{ + assert((ii > 0) && (ii < _sons.size())); + return _sons[ii]; +} + +QVector< XMLNode* > XMLInteriorNode::sons() +{ + return _sons; +} + +XMLInteriorNode::~XMLInteriorNode() +{ + for(QVector< XMLNode* >::iterator it = _sons.begin();it != _sons.end();++it) + delete (*it); +} + +void XMLInteriorNode::applyProcedure(Visitor& v) +{ + v(*this); +} \ No newline at end of file diff --git a/wrap/dae/xmldocumentmanaging.h b/wrap/dae/xmldocumentmanaging.h new file mode 100644 index 00000000..6d674b93 --- /dev/null +++ b/wrap/dae/xmldocumentmanaging.h @@ -0,0 +1,194 @@ +#ifndef _XML_DOCUMENT_MANAGING_H +#define _XML_DOCUMENT_MANAGING_H + +#include +#include +#include +#include +#include +#include +#include + +class XMLTag +{ +public: + typedef std::pair TagAttribute; + typedef QVector TagAttributes; + QString _tagname; + TagAttributes _attributes; + + XMLTag(const QString& tagname = QString(),const TagAttributes& attr = TagAttributes()) + :_tagname(tagname),_attributes(attr) + { + } + + virtual ~XMLTag() + { + } +}; + +class XMLLeafTag : public XMLTag +{ +public: + QVector _text; + + XMLLeafTag(const QString& tagname = QString(),const QVector& text = QVector()) + :XMLTag(tagname),_text(text) + { + } + + virtual ~XMLLeafTag() + { + } +}; + +class XMLDocumentWriter; + +class Visitor; + +class XMLNode +{ +public: + XMLNode(XMLTag* tag); + virtual ~XMLNode(); + + virtual void applyProcedure(Visitor& v) = 0; + + XMLTag* _tag; +}; + +class XMLInteriorNode : public XMLNode +{ +public: + XMLInteriorNode(XMLTag* tag); + + XMLNode* son(int ii); + + QVector< XMLNode* > sons(); + + void applyProcedure(Visitor& v); + + ~XMLInteriorNode(); + + QVector< XMLNode* > _sons; +}; + +class XMLLeafNode : public XMLNode +{ +public: + XMLLeafNode(XMLLeafTag* leaftag); + + void applyProcedure(Visitor& v); + virtual ~XMLLeafNode(); +}; + +class XMLDocument +{ +public: + XMLDocument(XMLInteriorNode* root) + :_root(root) + { + } + + ~XMLDocument() + { + delete (_root); + } + + XMLInteriorNode* _root; +}; + + +class Visitor +{ +public: + virtual void operator()(XMLLeafNode& leaf) = 0; + virtual void operator()(XMLInteriorNode& intnode) = 0; +}; + + +class XMLDocumentWriter : public Visitor +{ +private: + QXmlStreamWriter _stream; + QFile _file; + bool _error; + + void writeText(XMLLeafNode& node) + { + XMLLeafTag* leaftag = static_cast(node._tag); + for(QVector::iterator it = leaftag->_text.begin();it != leaftag->_text.end();++it) + { + QString tmp = ""; + if (it != leaftag->_text.begin()) + tmp = QString(" "); + _stream.writeCharacters(tmp + *it); + } + } + + void writeAttributes(XMLNode& node) + { + QXmlStreamAttributes attr; + for(XMLTag::TagAttributes::iterator it = node._tag->_attributes.begin();it != node._tag->_attributes.end();++it) + attr.append(it->first,it->second); + _stream.writeAttributes(attr); + } + + void recursiveStep(XMLInteriorNode& intnode) + { + QVector< XMLNode* > sons = intnode.sons(); + for(QVector< XMLNode* >::iterator its = sons.begin();its != sons.end();++its) + (*its)->applyProcedure(*this); + } + +public: + + void operator()(XMLLeafNode& node) + { + _stream.writeStartElement(node._tag->_tagname); + writeAttributes(node); + writeText(node); + _stream.writeEndElement(); + } + + void operator()(XMLInteriorNode& intnode) + { + _stream.writeStartElement(intnode._tag->_tagname); + writeAttributes(intnode); + recursiveStep(intnode); + _stream.writeEndElement(); + } + + void operator()(XMLDocument& doc) + { + _stream.writeStartDocument(); + operator()(*(doc._root)); + _stream.writeEndDocument(); + } + + void write(XMLDocument& doc) + { + (*this)(doc); + } + + bool isReliable() const + { + return !_error; + } + + XMLDocumentWriter(const char* filename,const bool autoformatting = true) + :_stream(),_file(filename),_error(false) + { + if (!_file.open(QIODevice::WriteOnly | QIODevice::Text)) + _error = true; + _stream.setDevice(&_file); + _stream.setAutoFormatting(autoformatting); + } + + ~XMLDocumentWriter() + { + _file.close(); + } +}; + +#endif \ No newline at end of file