1 /****************************************************************************
2 * VCGLib                                                            o o     *
3 * Visual and Computer Graphics Library                            o     o   *
4 *                                                                _   O  _   *
5 * Copyright(C) 2004-2008                                           \/)\/    *
6 * Visual Computing Lab                                            /\/|      *
7 * ISTI - Italian National Research Council                           |      *
8 *                                                                    \      *
9 * All rights reserved.                                                      *
10 *                                                                           *
11 * This program is free software; you can redistribute it and/or modify      *
12 * it under the terms of the GNU General Public License as published by      *
13 * the Free Software Foundation; either version 2 of the License, or         *
14 * (at your option) any later version.                                       *
15 *                                                                           *
16 * This program is distributed in the hope that it will be useful,           *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
19 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
20 * for more details.                                                         *
21 *                                                                           *
22 ****************************************************************************/
23 #ifndef _COLLADA_FORMAT_H
24 #define _COLLADA_FORMAT_H
25 
26 #include <wrap/dae/xmldocumentmanaging.h>
27 #include <vcg/space/point4.h>
28 #include <vcg/space/color4.h>
29 
30 #include <QtGui/QImage>
31 #include <QtCore/QVector>
32 
33 #include <QDateTime>
34 
35 
36 
37 
38 template<typename POINTTYPE>
coordCoordNumber39 struct CoordNumber{public:	static unsigned int coord()	{		return 0; 	}};
40 
41 template<> struct CoordNumber<vcg::Point2f> { public:	static unsigned int coord() { return 2;	} };
42 template<> struct CoordNumber<vcg::Point3f> { public:	static unsigned int coord() {	return 3;	} };
43 template<> struct CoordNumber<vcg::Point4f> { public: static unsigned int coord() {	return 4;	} };
44 
45 template<> struct CoordNumber<vcg::Color4b> { public:	static unsigned int coord() { return 4;	} };
46 
47 
48 namespace Collada
49 {
50 namespace Tags
51 {
52 	static const QString testSharp(const QString& str)
53 	{
54 		QString sharp = "";
55 		if (str.at(0) != '#')
56 			sharp = '#';
57 		return (sharp + str);
58 	}
59 
60 	class ColladaTag : public XMLTag
61 	{
62 	public:
63 		ColladaTag()
64 			:XMLTag("COLLADA")
65 		{
66 			_attributes.push_back(TagAttribute("xmlns","http://www.collada.org/2005/11/COLLADASchema"));
67 			_attributes.push_back(TagAttribute("version","1.4.1"));
68 		}
69 	};
70 
71 	class AssetTag : public XMLTag
72 	{
73 	public:
74 		AssetTag()
75 			:XMLTag("asset")
76 		{
77 		}
78 	};
79 
80 	class ContributorTag : public XMLTag
81 	{
82 	public:
83 		ContributorTag()
84 			:XMLTag("contributor")
85 		{
86 		}
87 	};
88 
89 	class AuthorTag : public XMLLeafTag
90 	{
91 	public:
92 		AuthorTag()
93 			:XMLLeafTag("author")
94 		{
95 			_text.push_back("VCGLab");
96 		}
97 	};
98 
99 	class AuthoringToolTag : public XMLLeafTag
100 	{
101 	public:
102 		AuthoringToolTag()
103 			:XMLLeafTag("authoring_tool")
104 		{
105 			_text.push_back("VCGLib | MeshLab");
106 		}
107 	};
108 
109 	class UpAxisTag : public XMLLeafTag
110 	{
111 	public:
112 		UpAxisTag(const QString& up = "Y_UP")
113 			:XMLLeafTag("up_axis")
114 		{
115 			_text.push_back(up);
116 		}
117 	};
118 
119 	class LibraryImagesTag : public XMLTag
120 	{
121 	public:
122 		LibraryImagesTag()
123 			:XMLTag("library_images")
124 		{
125 		}
126 	};
127 
128 	class ImageTag : public XMLTag
129 	{
130 	public:
131 		ImageTag(const QString& id,const QString& name)
132 			:XMLTag("image")
133 		{
134 			_attributes.push_back(TagAttribute("id",id));
135 			_attributes.push_back(TagAttribute("name",name));
136 		}
137 	};
138 
139 	class InitFromTag : public XMLLeafTag
140 	{
141 	public:
142 		InitFromTag(const QString& txtpathname)
143 			:XMLLeafTag("init_from")
144 		{
145 			_text.push_back(txtpathname);
146 		}
147 	};
148 
149 	class LibraryMaterialsTag : public XMLTag
150 	{
151 	public:
152 		LibraryMaterialsTag()
153 			:XMLTag("library_materials")
154 		{
155 		}
156 	};
157 
158 	class MaterialTag : public XMLTag
159 	{
160 	public:
161 		MaterialTag(const QString& id,const QString& name)
162 			:XMLTag("material")
163 		{
164 			_attributes.push_back(TagAttribute("id",id));
165 			_attributes.push_back(TagAttribute("name",name));
166 		}
167 	};
168 
169 	class InstanceEffectTag : public XMLLeafTag
170 	{
171 	public:
172 		InstanceEffectTag(const QString& url)
173 			:XMLLeafTag("instance_effect")
174 		{
175 			_attributes.push_back(TagAttribute("url",testSharp(url)));
176 		}
177 	};
178 
179 	class LibraryEffectsTag : public XMLTag
180 	{
181 	public:
182 		LibraryEffectsTag()
183 			:XMLTag("library_effects")
184 		{
185 		}
186 	};
187 
188 	class EffectTag : public XMLTag
189 	{
190 	public:
191 		EffectTag(const QString& id)
192 			:XMLTag("effect")
193 		{
194 			_attributes.push_back(TagAttribute("id",id));
195 		}
196 	};
197 
198 	class ProfileCommonTag : public XMLTag
199 	{
200 	public:
201 		ProfileCommonTag()
202 			:XMLTag("profile_COMMON")
203 		{
204 		}
205 	};
206 
207 	class NewParamTag : public XMLTag
208 	{
209 	public:
210 		NewParamTag(const QString& sid)
211 			:XMLTag("newparam")
212 		{
213 			_attributes.push_back(TagAttribute("sid",sid));
214 		}
215 	};
216 
217 	class SurfaceTag : public XMLTag
218 	{
219 	public:
220 		SurfaceTag(const QString& type = QString("2D"))
221 			:XMLTag("surface")
222 		{
223 			_attributes.push_back(TagAttribute("type",type));
224 		}
225 	};
226 
227 	class FormatTag : public XMLLeafTag
228 	{
229 	public:
230 		FormatTag(const QString& format)
231 			:XMLLeafTag("format")
232 		{
233 			_text.push_back(format);
234 		}
235 	};
236 
237 	class Sampler2DTag : public XMLTag
238 	{
239 	public:
240 		Sampler2DTag()
241 			:XMLTag("sampler2D")
242 		{
243 		}
244 	};
245 
246 	class SourceTag : public XMLLeafTag
247 	{
248 	public:
249 		SourceTag(const QString& id,const QString& name)
250 			:XMLLeafTag("source")
251 		{
252 			_attributes.push_back(TagAttribute("id",id));
253 			_attributes.push_back(TagAttribute("name",name));
254 		}
255 
256 		SourceTag(const QString& source)
257 			:XMLLeafTag("source")
258 		{
259 			_text.push_back(source);
260 		}
261 	};
262 
263 	class MinFilterTag : public XMLLeafTag
264 	{
265 	public:
266 		MinFilterTag(const QString& filter)
267 			:XMLLeafTag("minfilter")
268 		{
269 			_text.push_back(filter);
270 		}
271 	};
272 
273 	class MagFilterTag : public XMLLeafTag
274 	{
275 	public:
276 		MagFilterTag(const QString& filter)
277 			:XMLLeafTag("magfilter")
278 		{
279 			_text.push_back(filter);
280 		}
281 	};
282 
283 	class TechniqueTag : public XMLTag
284 	{
285 	public:
286 		TechniqueTag(const QString& sid)
287 			:XMLTag("technique")
288 		{
289 			_attributes.push_back(TagAttribute("sid",sid));
290 		}
291 	};
292 
293 	class TechniqueCommonTag : public XMLTag
294 	{
295 	public:
296 		TechniqueCommonTag()
297 			:XMLTag("technique_common")
298 		{
299 		}
300 	};
301 
302 	class BlinnTag : public XMLTag
303 	{
304 	public:
305 		BlinnTag()
306 			:XMLTag("blinn")
307 		{
308 		}
309 	};
310 
311 	class EmissionTag : public XMLTag
312 	{
313 	public:
314 		EmissionTag()
315 			:XMLTag("emission")
316 		{
317 		}
318 	};
319 
320 	class ColorTag : public XMLLeafTag
321 	{
322 	public:
323 		ColorTag(const float r,const float g,const float b,const float a)
324 			:XMLLeafTag("color")
325 		{
326 
327 			_text.push_back(QString::number(r));
328 			_text.push_back(QString::number(g));
329 			_text.push_back(QString::number(b));
330 			_text.push_back(QString::number(a));
331 		}
332 	};
333 
334 	class AmbientTag : public XMLTag
335 	{
336 	public:
337 		AmbientTag()
338 			:XMLTag("ambient")
339 		{
340 		}
341 	};
342 
343 	class DiffuseTag : public XMLTag
344 	{
345 	public:
346 		DiffuseTag()
347 			:XMLTag("diffuse")
348 		{
349 		}
350 	};
351 
352 	class TextureTag : public XMLLeafTag
353 	{
354 	public:
355 		TextureTag(const QString& texture,const QString& texcoord)
356 			:XMLLeafTag("texture")
357 		{
358 			_attributes.push_back(TagAttribute("texture",texture));
359 			_attributes.push_back(TagAttribute("texcoord",texcoord));
360 		}
361 	};
362 
363 	class SpecularTag : public XMLTag
364 	{
365 	public:
366 		SpecularTag()
367 			:XMLTag("specular")
368 		{
369 		}
370 	};
371 
372 	class ShininessTag : public XMLTag
373 	{
374 	public:
375 		ShininessTag()
376 			:XMLTag("shininess")
377 		{
378 		}
379 	};
380 
381 	class FloatTag : public XMLLeafTag
382 	{
383 	public:
384 		FloatTag(const float floatnum)
385 			:XMLLeafTag("float")
386 		{
387 			_text.push_back(QString::number(floatnum));
388 		}
389 	};
390 
391 	class ReflectiveTag : public XMLTag
392 	{
393 	public:
394 		ReflectiveTag()
395 			:XMLTag("reflective")
396 		{
397 		}
398 	};
399 
400 	class ReflectivityTag : public XMLTag
401 	{
402 	public:
403 		ReflectivityTag()
404 			:XMLTag("reflectivity")
405 		{
406 		}
407 	};
408 
409 	class TransparentTag : public XMLTag
410 	{
411 	public:
412 		TransparentTag()
413 			:XMLTag("transparent")
414 		{
415 		}
416 	};
417 
418 	class TransparencyTag : public XMLTag
419 	{
420 	public:
421 		TransparencyTag()
422 			:XMLTag("transparency")
423 		{
424 		}
425 	};
426 
427 	class IndexOfRefractionTag : public XMLTag
428 	{
429 	public:
430 		IndexOfRefractionTag()
431 			:XMLTag("index_of_refraction")
432 		{
433 		}
434 	};
435 
436 	class LibraryGeometriesTag : public XMLTag
437 	{
438 	public:
439 		LibraryGeometriesTag()
440 			:XMLTag("library_geometries")
441 		{
442 		}
443 	};
444 
445 	class GeometryTag : public XMLTag
446 	{
447 	public:
448 		GeometryTag(const QString& id,const QString& name)
449 			:XMLTag("geometry")
450 		{
451 			_attributes.push_back(TagAttribute("id",id));
452 			_attributes.push_back(TagAttribute("name",name));
453 		}
454 	};
455 
456 	class MeshTag : public XMLTag
457 	{
458 	public:
459 		MeshTag()
460 			:XMLTag("mesh")
461 		{
462 		}
463 	};
464 
465 	class ArraySourceTag : public XMLTag
466 	{
467 	public:
468 		ArraySourceTag(const QString& id,const QString& name)
469 			:XMLTag("source")
470 		{
471 			_attributes.push_back(TagAttribute("id",id));
472 			_attributes.push_back(TagAttribute("name",name));
473 		}
474 	};
475 
476 	class FloatArrayTag : public XMLLeafTag
477 	{
478 	public:
479 		enum ARRAYSEMANTIC {VERTPOSITION,VERTNORMAL,VERTCOLOR, FACENORMAL,WEDGETEXCOORD};
480 
481 		template<typename MESHTYPE>
482 		FloatArrayTag(const QString& id,const int count,const MESHTYPE& m,ARRAYSEMANTIC sem,const unsigned int componenttype)
483 			:XMLLeafTag("float_array")
484 		{
485 			_attributes.push_back(TagAttribute("id",id));
486 			_attributes.push_back(TagAttribute("count",QString::number(count)));
487 
488 			if ((sem == VERTPOSITION) || (sem == VERTNORMAL) || (sem == VERTCOLOR))
489 			{
490 				for(typename MESHTYPE::ConstVertexIterator vit = m.vert.begin();vit != m.vert.end();++vit)
491 				{
492 					for(unsigned int ii = 0; ii < componenttype;++ii)
493 					{
494 						if (sem == VERTPOSITION)
495 							_text.push_back(QString::number(vit->P()[ii]));
496 						else if (sem == VERTCOLOR)
497 							_text.push_back(QString::number((vit->C()[ii])/255.0));
498 						else
499 						{
500 							typename MESHTYPE::VertexType::NormalType r = vit->cN();
501 							r.Normalize();
502 							_text.push_back(QString::number(r[ii]));
503 
504 						}
505 					}
506 				}
507 			}
508 			else
509 			{
510 				for(typename MESHTYPE::ConstFaceIterator fit = m.face.begin();fit != m.face.end();++fit)
511 				{
512 					if (sem == FACENORMAL)
513 					{
514 						for(unsigned int ii = 0; ii < componenttype;++ii)
515 						{
516 								typename MESHTYPE::FaceType::NormalType r = fit->cN();
517 								r.Normalize();
518 								_text.push_back(QString::number(r[ii]));
519 						}
520 					}
521 					else
522 					{
523 						for(unsigned int ii = 0; ii < 3;++ii)
524 						{
525 							_text.push_back(QString::number(fit->cWT(ii).U()));
526 							_text.push_back(QString::number(fit->cWT(ii).V()));
527 						}
528 					}
529 				}
530 			}
531 		}
532 	};
533 
534 	//class FloatWedgeArrayTag : public XMLLeafTag
535 	//{
536 	//public:
537 	//	template<typename MESHTYPE,typename SIMPLEXACCESSOR>
538 	//	FloatWedgeArrayTag(const QString& id,const int count,const MESHTYPE& m,const AccessorComponentNumberInfo<MESHTYPE,SIMPLEXACCESSOR>& accessor)
539 	//		:XMLLeafTag("float_array")
540 	//	{
541 	//		_attributes.push_back(TagAttribute("id",id));
542 	//		_attributes.push_back(TagAttribute("count",QString::number(count)));
543 	//		for(typename SIMPLEXACCESSOR::ConstIterator it= accessor._a.begin();it != accessor._a.end(); ++it)
544 	//		{
545 	//			for(unsigned int ii = 0; ii < 3;++ii)
546 	//			{
547 	//				_text.push_back(QString::number(accessor._a(*it,ii).U()));
548 	//				_text.push_back(QString::number(accessor._a(*it,ii).V()));
549 	//			}
550 	//		}
551 	//	}
552 	//};
553 
554 	class AccessorTag : public XMLTag
555 	{
556 	public:
557 		AccessorTag(const int count,const QString& source,const int stride)
558 			:XMLTag("accessor")
559 		{
560 			_attributes.push_back(TagAttribute("count",QString::number(count)));
561 			_attributes.push_back(TagAttribute("source",testSharp(source)));
562 			_attributes.push_back(TagAttribute("stride",QString::number(stride)));
563 		}
564 	};
565 
566 	class ParamTag : public XMLTag
567 	{
568 	public:
569 		ParamTag(const QString& name,const QString& type)
570 			:XMLTag("param")
571 		{
572 			_attributes.push_back(TagAttribute("name",name));
573 			_attributes.push_back(TagAttribute("type",type));
574 		}
575 	};
576 
577 	class VerticesTag : public XMLTag
578 	{
579 	public:
580 		VerticesTag(const QString& id)
581 			:XMLTag("vertices")
582 		{
583 			_attributes.push_back(TagAttribute("id",id));
584 		}
585 	};
586 
587 	class InputTag : public XMLTag
588 	{
589 	public:
590 
591 		InputTag(const QString& semantic,const QString& source)
592 			:XMLTag("input")
593 		{
594 			_attributes.push_back(TagAttribute("semantic",semantic));
595 			_attributes.push_back(TagAttribute("source",testSharp(source)));
596 		}
597 
598 		InputTag(const int offset,const QString& semantic,const QString& source)
599 			:XMLTag("input")
600 		{
601 			_attributes.push_back(TagAttribute("offset",QString::number(offset)));
602 			_attributes.push_back(TagAttribute("semantic",semantic));
603 			_attributes.push_back(TagAttribute("source",testSharp(source)));
604 		}
605 	};
606 
607 	class TrianglesTag : public XMLTag
608 	{
609 	public:
610 		TrianglesTag(const int count)
611 			:XMLTag("triangles")
612 		{
613 			_attributes.push_back(TagAttribute("count",QString::number(count)));
614 		}
615 
616 		TrianglesTag(const int count,const QString& material)
617 			:XMLTag("triangles")
618 		{
619 			_attributes.push_back(TagAttribute("count",QString::number(count)));
620 			_attributes.push_back(TagAttribute("material",material));
621 		}
622 	};
623 
624 	class PTag : public XMLLeafTag
625 	{
626 	public:
627 		template<typename MESHTYPE>
628 		PTag(const MESHTYPE& m,const unsigned int nedge,bool vcol=false, bool norm = false,bool texcoord = false)
629 			:XMLLeafTag("p")
630 		{
631 			int cont = 0;
632 			for(typename MESHTYPE::ConstFaceIterator it= m.face.begin();it != m.face.end(); ++it)
633 			{
634 				for(unsigned int ii = 0; ii < nedge; ++ii)
635 				{
636 					int dist  = vcg::tri::Index(m,it->cV(ii));
637 					_text.push_back(QString::number(dist));
638 					if (vcol)
639 						_text.push_back(QString::number(dist));
640 					if (norm)
641 						_text.push_back(QString::number(cont));
642 					if (texcoord)
643 						_text.push_back(QString::number(cont * nedge + ii));
644 				}
645 				++cont;
646 			}
647 		}
648 
649 		template<typename MESHTYPE>
650 		PTag(const MESHTYPE& m,const unsigned int nedge,QVector<int>& patchfaces,bool vcol = false, bool norm = false,bool texcoord = false)
651 			:XMLLeafTag("p")
652 		{
653 			int cont = 0;
654 			for(QVector<int>::iterator it = patchfaces.begin();it != patchfaces	.end(); ++it)
655 			{
656 				for(unsigned int ii = 0; ii < nedge; ++ii)
657 				{
658 					const typename MESHTYPE::FaceType& f = m.face[*it];
659 					int dist  = f.cV(ii) - &(*m.vert.begin());
660 					_text.push_back(QString::number(dist));
661 					if (vcol)
662 						_text.push_back(QString::number(dist));
663 					if (norm)
664 						_text.push_back(QString::number(*it));
665 					if (texcoord)
666 						_text.push_back(QString::number(*it * nedge + ii));
667 				}
668 				++cont;
669 			}
670 		}
671 	};
672 
673 	class LibraryVisualScenesTag : public XMLTag
674 	{
675 	public:
676 		LibraryVisualScenesTag()
677 			:XMLTag("library_visual_scenes")
678 		{
679 		}
680 	};
681 
682 	class VisualSceneTag : public XMLTag
683 	{
684 	public:
685 		VisualSceneTag(const QString& id,const QString& name)
686 			:XMLTag("visual_scene")
687 		{
688 			_attributes.push_back(TagAttribute("id",id));
689 			_attributes.push_back(TagAttribute("name",name));
690 		}
691 	};
692 
693 	class NodeTag : public XMLTag
694 	{
695 	public:
696 		NodeTag(const QString& id,const QString& name)
697 			:XMLTag("node")
698 		{
699 			_attributes.push_back(TagAttribute("id",id));
700 			_attributes.push_back(TagAttribute("name",name));
701 		}
702 	};
703 
704 	class RotateTag : public XMLLeafTag
705 	{
706 	public:
707 		RotateTag(const QString& sid,const vcg::Point4f& p)
708 			:XMLLeafTag("rotate")
709 		{
710 			_attributes.push_back(TagAttribute("sid",sid));
711 
712 			for(unsigned int ii =0;ii < 4; ++ii)
713 				_text.push_back(QString::number(p[ii]));
714 		}
715 	};
716 
717 	class TranslateTag : public XMLLeafTag
718 	{
719 	public:
720 		TranslateTag(const QString& sid,const vcg::Point4f& p)
721 			:XMLLeafTag("translate")
722 		{
723 			_attributes.push_back(TagAttribute("sid",sid));
724 
725 			for(unsigned int ii =0;ii < 4; ++ii)
726 				_text.push_back(QString::number(p[ii]));
727 		}
728 	};
729 
730 	class InstanceGeometryTag : public XMLTag
731 	{
732 	public:
733 		InstanceGeometryTag(const QString& url)
734 			:XMLTag("instance_geometry")
735 		{
736 			_attributes.push_back(TagAttribute("url",testSharp(url)));
737 		}
738 	};
739 
740 	class BindMaterialTag : public XMLTag
741 	{
742 	public:
743 		BindMaterialTag()
744 			:XMLTag("bind_material")
745 		{
746 		}
747 	};
748 
749 	class InstanceMaterialTag : public XMLTag
750 	{
751 	public:
752 		InstanceMaterialTag(const QString& symbol,const QString& target)
753 			:XMLTag("instance_material")
754 		{
755 			_attributes.push_back(TagAttribute("symbol",symbol));
756 			_attributes.push_back(TagAttribute("target",testSharp(target)));
757 		}
758 	};
759 
760 	class BindVertexInputTag : public XMLTag
761 	{
762 	public:
763 		BindVertexInputTag(const QString& semantic,const QString& input_semantic,const QString& /*input_set*/)
764 			:XMLTag("bind_vertex_input")
765 		{
766 			_attributes.push_back(TagAttribute("semantic",semantic));
767 			_attributes.push_back(TagAttribute("input_semantic",input_semantic));
768 		}
769 	};
770 
771 	class SceneTag : public XMLTag
772 	{
773 	public:
774 		SceneTag()
775 			:XMLTag("scene")
776 		{
777 		}
778 	};
779 
780 	class CreatedTag : public XMLLeafTag//added
781 	{
782 	public:
783 		CreatedTag()
784 			:XMLLeafTag("created")
785 		{
786 			QDateTime dateCreated = QDateTime::currentDateTime().toUTC();
787 			QString dateCreatedStr = dateCreated.toString();
788 			_text.push_back(dateCreatedStr);
789 		}
790 	};
791 
792 	class ModifiedTag : public XMLLeafTag//added
793 	{
794 	public:
795 		ModifiedTag()
796 			:XMLLeafTag("modified")
797 		{
798 			QDateTime dateModified = QDateTime::currentDateTime().toUTC();
799 			QString dateModifiedStr = dateModified.toString();
800 			_text.push_back(dateModifiedStr);
801 		}
802 	};
803 
804 	class InstanceVisualSceneTag : public XMLTag
805 	{
806 	public:
807 		InstanceVisualSceneTag(const QString& url)
808 			:XMLTag("instance_visual_scene")
809 		{
810 			_attributes.push_back(TagAttribute("url",testSharp(url)));
811 		}
812 	};
813 } //Tags
814 
815 class DocumentManager
816 {
817 private:
818 	static void connectHierarchyNode(XMLInteriorNode* node0,XMLInteriorNode* node1,XMLLeafNode* leaf)
819 	{
820 		node1->_sons.push_back(leaf);
821 		node0->_sons.push_back(node1);
822 	}
823 
824 	static void connectHierarchyNode(XMLInteriorNode* node0,XMLInteriorNode* node1,XMLInteriorNode* node2,XMLInteriorNode* node3,XMLNode* node4)
825 	{
826 		node3->_sons.push_back(node4);
827 		node2->_sons.push_back(node3);
828 		node1->_sons.push_back(node2);
829 		node0->_sons.push_back(node1);
830 	}
831 
832 	static void connectHierarchyNode(XMLInteriorNode* node0,XMLInteriorNode* node1,XMLInteriorNode* node2,XMLInteriorNode* node3)
833 	{
834 		node2->_sons.push_back(node3);
835 		node1->_sons.push_back(node2);
836 		node0->_sons.push_back(node1);
837 	}
838 
839 	static void connectHierarchyNode(XMLInteriorNode* node0,XMLInteriorNode* node1,XMLInteriorNode* node2)
840 	{
841 		node1->_sons.push_back(node2);
842 		node0->_sons.push_back(node1);
843 	}
844 
845 	template<typename MESHMODELTYPE>
846 	static void splitMeshInTexturedPatches(const MESHMODELTYPE& m,QVector<QVector<int> >& patches)
847 	{
848 		patches.resize(m.textures.size());
849 		int cc = 0;
850 		for(typename MESHMODELTYPE::ConstFaceIterator itf = m.face.begin();itf != m.face.end();++itf)
851 		{
852 			int tmp = itf->cWT(0).N();
853 			assert(tmp>=0 && tmp<patches.size());
854 			patches[tmp].push_back(cc);
855 			++cc;
856 		}
857 	}
858 
859 public:
860 	template<typename MESHMODELTYPE>
861 	static XMLDocument* createColladaDocument(const MESHMODELTYPE& m,const int mask)
862 	{
863 		//for now we export only triangularface
864 		const unsigned int edgefacenum = 3;
865 		typedef XMLInteriorNode XNode;
866 		typedef XMLLeafNode XLeaf;
867 
868 		XNode* root = new XNode(new Tags::ColladaTag());
869 		XNode* assetnode = new XNode(new Tags::AssetTag());
870 		XNode* contributornode = new XNode(new Tags::ContributorTag());
871 		contributornode->_sons.push_back(new XLeaf(new Tags::AuthorTag()));
872 		contributornode->_sons.push_back(new XLeaf(new Tags::AuthoringToolTag()));
873 
874 		assetnode->_sons.push_back(contributornode);
875 		assetnode->_sons.push_back(new XLeaf(new Tags::CreatedTag()));//added
876 		assetnode->_sons.push_back(new XLeaf(new Tags::ModifiedTag()));
877 		assetnode->_sons.push_back(new XLeaf(new Tags::UpAxisTag()));
878 		root->_sons.push_back(assetnode);
879 
880 		XNode* libimages = NULL;
881 		for(unsigned int ii = 0;ii < m.textures.size();++ii)
882 		{
883 			if ( ii == 0)
884 				libimages = new XNode(new Tags::LibraryImagesTag());
885 			QString subfix = QString::number(ii);
886 			XNode* imagenode = new XNode(new Tags::ImageTag(QString("texture") + subfix,QString("texture") + subfix));
887 			XLeaf* initfromnode = new XLeaf(new Tags::InitFromTag(QString::fromStdString(m.textures[ii])));
888 			imagenode->_sons.push_back(initfromnode);
889 			libimages->_sons.push_back(imagenode);
890 			if (ii == 0)
891 				root->_sons.push_back(libimages);
892 		}
893 
894 		XNode* libmaterials = NULL;
895 		for(unsigned int ii = 0;ii < m.textures.size();++ii)
896 		{
897 			if ( ii == 0)
898 				libmaterials = new XNode(new Tags::LibraryMaterialsTag());
899 			QString subfix = QString::number(ii);
900 			QString mat = "material" + subfix;
901 			XNode* materialnode = new XNode(new Tags::MaterialTag(mat,mat));
902 			XLeaf* instanceeff = new XLeaf(new Tags::InstanceEffectTag(mat+"-fx"));
903 			materialnode->_sons.push_back(instanceeff);
904 			libmaterials->_sons.push_back(materialnode);
905 			if ( ii == 0)
906 				root->_sons.push_back(libmaterials);
907 		}
908 
909 		XNode* libeffects = NULL;
910 		for(unsigned int ii = 0;ii < m.textures.size();++ii)
911 		{
912 			if ( ii == 0)
913 				libeffects = new XNode(new Tags::LibraryEffectsTag());
914 			QString subfix = QString::number(ii);
915 			QString mat = "material" + subfix + "-fx";
916 			XNode* effectnode = new XNode(new Tags::EffectTag(mat));
917 			XNode* procommnode = new XNode(new Tags::ProfileCommonTag());
918 			QString tex = QString("texture")+subfix;
919 			XNode* newparamnode = new XNode(new Tags::NewParamTag(tex+"-surface"));
920 			XNode* surfacenode = new XNode(new Tags::SurfaceTag());
921 			XLeaf* initfromnode = new XLeaf(new Tags::InitFromTag(tex));
922 			QImage img(QString::fromStdString(m.textures[ii]));
923 			QImage::Format f = img.format();
924 			QString form = "R8G8B8";
925 			if (f==QImage::Format_ARGB32)
926 				form = "A8R8G8B8";
927 			XLeaf* formatnode = new XLeaf(new Tags::FormatTag(form));
928 			surfacenode->_sons.push_back(initfromnode);
929 			surfacenode->_sons.push_back(formatnode);
930 			newparamnode->_sons.push_back(surfacenode);
931 			procommnode->_sons.push_back(newparamnode);
932 
933 			XNode* newparamnode2 = new XNode(new Tags::NewParamTag(tex+"-sampler"));
934 			XNode* samplernode = new XNode(new Tags::Sampler2DTag());
935 			XLeaf* sourcenode = new XLeaf(new Tags::SourceTag(tex+"-surface"));
936 			XLeaf* minfilt = new XLeaf(new Tags::MinFilterTag("LINEAR"));
937 			XLeaf* magfilt = new XLeaf(new Tags::MagFilterTag("LINEAR"));
938 			samplernode->_sons.push_back(sourcenode);
939 			samplernode->_sons.push_back(minfilt);
940 			samplernode->_sons.push_back(magfilt);
941 			newparamnode2->_sons.push_back(samplernode);
942 			procommnode->_sons.push_back(newparamnode2);
943 
944 			XNode* technode = new XNode(new Tags::TechniqueTag("common"));
945 			XNode* blinnnode = new XNode(new Tags::BlinnTag());
946 
947 			XNode* diffusenode = new XNode(new Tags::DiffuseTag());
948 			XLeaf* texturenode = new XLeaf(new Tags::TextureTag(tex+"-sampler","UVSET0"));
949 
950 			connectHierarchyNode(blinnnode,diffusenode,texturenode);
951 			connectHierarchyNode(procommnode,technode,blinnnode);
952 
953 			effectnode->_sons.push_back(procommnode);
954 			libeffects->_sons.push_back(effectnode);
955 			if ( ii == 0)
956 				root->_sons.push_back(libeffects);
957 		}
958 
959 		XNode* libgeo = new XNode(new Tags::LibraryGeometriesTag());
960 		QString subfix = "0";
961 		QString shape = "shape" + subfix;
962 		XNode* geometrynode = new XNode(new Tags::GeometryTag(shape+"-lib",shape));
963 		XNode* meshnode = new XNode(new Tags::MeshTag());
964 		XNode* sourcepos = new XNode(new Tags::SourceTag(shape+"-lib-positions","position"));
965 		//AccessorComponentNumberInfo<MESHMODELTYPE,MeshAccessors::VertexPositionAccessor<const MESHMODELTYPE>> acc(m);
966 		unsigned int return_component_number = CoordNumber<typename MESHMODELTYPE::CoordType>::coord();
967 		XLeaf* floatarr = new XLeaf(new Tags::FloatArrayTag(shape+"-lib-positions-array",m.vert.size() * return_component_number,m,Tags::FloatArrayTag::VERTPOSITION,return_component_number));
968 		XNode* techcommnode = new XNode(new Tags::TechniqueCommonTag());
969 		XNode* accessornode = new XNode(new Tags::AccessorTag(m.vert.size(),shape+"-lib-positions-array",return_component_number));
970 		XNode* paramx = new XNode(new Tags::ParamTag("X","float"));
971 		XNode* paramy = new XNode(new Tags::ParamTag("Y","float"));
972 		XNode* paramz = new XNode(new Tags::ParamTag("Z","float"));
973 
974 		sourcepos->_sons.push_back(floatarr);
975 		accessornode->_sons.push_back(paramx);
976 		accessornode->_sons.push_back(paramy);
977 		accessornode->_sons.push_back(paramz);
978 
979 		techcommnode->_sons.push_back(accessornode);
980 		sourcepos->_sons.push_back(techcommnode);
981 
982 		meshnode->_sons.push_back(sourcepos);
983 
984 
985 		//CHANGE THIS PIECE OF CODE!
986 		bool normalmask = bool((mask & vcg::tri::io::Mask::IOM_FACENORMAL) || (mask & vcg::tri::io::Mask::IOM_WEDGNORMAL) || (mask & vcg::tri::io::Mask::IOM_VERTNORMAL));
987 		if (normalmask)
988 		{
989 			XNode* sourcenormal = new XNode(new Tags::SourceTag(shape+"-lib-normals","normal"));
990 
991 			//we export only triangular face
992 			XLeaf* floatnormarr = new XLeaf(new Tags::FloatArrayTag(shape+"-lib-normals-array",m.face.size() * return_component_number,m,Tags::FloatArrayTag::FACENORMAL,return_component_number));
993 			XNode* techcommnormnode = new XNode(new Tags::TechniqueCommonTag());
994 			XNode* accessornormnode = new XNode(new Tags::AccessorTag(m.face.size(),shape+"-lib-normals-array",return_component_number));
995 
996 			//I have to make up the following piece of code
997 			XNode* paramnormx = new XNode(new Tags::ParamTag("X","float"));
998 			XNode* paramnormy = new XNode(new Tags::ParamTag("Y","float"));
999 			XNode* paramnormz = new XNode(new Tags::ParamTag("Z","float"));
1000 
1001 			sourcenormal->_sons.push_back(floatnormarr);
1002 
1003 			accessornormnode->_sons.push_back(paramnormx);
1004 			accessornormnode->_sons.push_back(paramnormy);
1005 			accessornormnode->_sons.push_back(paramnormz);
1006 
1007 			techcommnormnode->_sons.push_back(accessornormnode);
1008 			sourcenormal->_sons.push_back(techcommnormnode);
1009 
1010 			meshnode->_sons.push_back(sourcenormal);
1011 		}
1012 
1013 		//CHANGE THIS PIECE OF CODE!
1014 		bool vcolormask = bool((mask & vcg::tri::io::Mask::IOM_VERTCOLOR));
1015 		if (vcolormask)
1016 		{
1017 			unsigned int color_component_number = 4;
1018 			XNode* sourcevcolor = new XNode(new Tags::SourceTag(shape+"-lib-vcolor","vcolor"));
1019 
1020 			//we export only triangular face
1021 			XLeaf* floatvcolorarr = new XLeaf(new Tags::FloatArrayTag(shape+"-lib-vcolor-array",m.vert.size() * color_component_number,m,Tags::FloatArrayTag::VERTCOLOR,color_component_number));
1022 			XNode* techcommvcolornode = new XNode(new Tags::TechniqueCommonTag());
1023 			XNode* accessorvcolornode = new XNode(new Tags::AccessorTag(m.vert.size(),shape+"-lib-vcolor-array",color_component_number));
1024 
1025 			//I have to make up the following piece of code
1026 			XNode* paramvcolorx = new XNode(new Tags::ParamTag("R","float"));
1027 			XNode* paramvcolory = new XNode(new Tags::ParamTag("G","float"));
1028 			XNode* paramvcolorz = new XNode(new Tags::ParamTag("B","float"));
1029 			XNode* paramvcolora = new XNode(new Tags::ParamTag("A","float"));
1030 
1031 			sourcevcolor->_sons.push_back(floatvcolorarr);
1032 
1033 			accessorvcolornode->_sons.push_back(paramvcolorx);
1034 			accessorvcolornode->_sons.push_back(paramvcolory);
1035 			accessorvcolornode->_sons.push_back(paramvcolorz);
1036 			accessorvcolornode->_sons.push_back(paramvcolora);
1037 
1038 			techcommvcolornode->_sons.push_back(accessorvcolornode);
1039 			sourcevcolor->_sons.push_back(techcommvcolornode);
1040 
1041 			meshnode->_sons.push_back(sourcevcolor);
1042 		}
1043 
1044 		bool texmask = bool(mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD);
1045 		if (texmask)
1046 		{
1047 			XNode* sourcewedge = new XNode(new Tags::SourceTag(shape+"-lib-map","map"));
1048 			return_component_number = CoordNumber<typename MESHMODELTYPE::FaceType::TexCoordType::PointType>::coord();
1049 			//we export only triangular face
1050 			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));
1051 			XNode* techcommwedgenode = new XNode(new Tags::TechniqueCommonTag());
1052 			XNode* accessorwedgenode = new XNode(new Tags::AccessorTag(m.face.size() * edgefacenum,shape+"-lib-map-array",return_component_number));
1053 
1054 			//I have to make up the following piece of code
1055 			XNode* paramwedgeu = new XNode(new Tags::ParamTag("U","float"));
1056 			XNode* paramwedgev = new XNode(new Tags::ParamTag("V","float"));
1057 
1058 			sourcewedge->_sons.push_back(floatwedgearr);
1059 
1060 			accessorwedgenode->_sons.push_back(paramwedgeu);
1061 			accessorwedgenode->_sons.push_back(paramwedgev);
1062 
1063 			techcommwedgenode->_sons.push_back(accessorwedgenode);
1064 			sourcewedge->_sons.push_back(techcommwedgenode);
1065 
1066 			meshnode->_sons.push_back(sourcewedge);
1067 		}
1068 
1069 		XNode* vertnode = new XNode(new Tags::VerticesTag(shape+"-lib-vertices"));
1070 		XNode* inputposnode = new XNode(new Tags::InputTag("POSITION",shape+"-lib-positions"));
1071 		vertnode->_sons.push_back(inputposnode);
1072 
1073 		//XNode* inputvcolnode = new XNode(new Tags::InputTag("COLOR",shape+"-lib-vcolor"));
1074 		//vertnode->_sons.push_back(inputvcolnode);
1075 
1076 		meshnode->_sons.push_back(vertnode);
1077 		XNode* trianglesnode = NULL;
1078 		//if ((m.textures.size() == 0) || (!texmask))
1079 		//{
1080 		//	//there isn't any texture file
1081 		//	trianglesnode = new XNode(new Tags::TrianglesTag(m.face.size()));
1082 		//}
1083 		//else
1084 		//{
1085 		//	std::vector<std::vector<int>> _mytripatches(m.textures.size());
1086 		//	if ((texmask) && (m.textures.size() > 1))
1087 		//	{
1088 		//		//there are many textures files - I have to split the mesh in triangular patches that share the same texture's file.
1089 		//		for(MESHMODELTYPE::ConstFaceIterator itf = m.face.begin();itf != m.face.end();++itf)
1090 		//		{
1091 		//
1092 		//		}
1093 		//		trianglesnode = new XNode(new Tags::TrianglesTag(m.face.size(),"instancematerial"));
1094 		//}
1095 
1096 		QVector<QVector<int> > mytripatches;
1097 		if ((texmask) && (m.textures.size() != 0))
1098 			splitMeshInTexturedPatches(m,mytripatches);
1099 
1100 		QVector<QVector<int> >::iterator itp = mytripatches.begin();
1101 		int indmat = 0;
1102 		do
1103 		{
1104 			if ((m.textures.size() == 0) || (!texmask))
1105 			{
1106 				//there isn't any texture file
1107 				trianglesnode = new XNode(new Tags::TrianglesTag(m.face.size()));
1108 			}
1109 			else
1110 				trianglesnode = new XNode(new Tags::TrianglesTag(mytripatches[indmat].size(),"material" + QString::number(indmat)));
1111 
1112 			XNode* inputtrinode = new XNode(new Tags::InputTag(0,"VERTEX",shape+"-lib-vertices"));
1113 			trianglesnode->_sons.push_back(inputtrinode);
1114 
1115 			int offs=1;
1116 			if (vcolormask)
1117 			{
1118 				XNode* inputvcolnode = new XNode(new Tags::InputTag(offs,"COLOR",shape+"-lib-vcolor"));
1119 				trianglesnode->_sons.push_back(inputvcolnode);
1120 				++offs;
1121 			}
1122 
1123 			if (normalmask)
1124 			{
1125 				XNode* inputnormnode = new XNode(new Tags::InputTag(offs,"NORMAL",shape+"-lib-normals"));
1126 				trianglesnode->_sons.push_back(inputnormnode);
1127 				++offs;
1128 			}
1129 
1130 			if (texmask)
1131 			{
1132 				XNode* inputwedgenode = new XNode(new Tags::InputTag(offs,"TEXCOORD",shape+"-lib-map"));
1133 				trianglesnode->_sons.push_back(inputwedgenode);
1134 				offs++;
1135 			}
1136 
1137 			XLeaf* polyleaf = NULL;
1138 			if (itp == mytripatches.end())
1139 				polyleaf = new XLeaf(new Tags::PTag(m,edgefacenum,vcolormask,normalmask,texmask));
1140 			else
1141 				polyleaf = new XLeaf(new Tags::PTag(m,edgefacenum,(*itp),vcolormask,normalmask,texmask));
1142 
1143 			trianglesnode->_sons.push_back(polyleaf);
1144 			meshnode->_sons.push_back(trianglesnode);
1145 
1146 			++indmat;
1147 			if (itp != mytripatches.end())
1148 				++itp;
1149 		}while(itp != mytripatches.end());
1150 
1151 		connectHierarchyNode(libgeo,geometrynode,meshnode);
1152 		root->_sons.push_back(libgeo);
1153 
1154 		XNode* libvisualnode = new XNode(new Tags::LibraryVisualScenesTag());
1155 		XNode* visualscenenode = new XNode(new Tags::VisualSceneTag("VisualSceneNode","VisualScene"));
1156 		XNode* nodenode = new XNode(new Tags::NodeTag("node","node"));
1157 		XNode* instgeonode = new XNode(new Tags::InstanceGeometryTag(shape+"-lib"));
1158 		if (m.textures.size() > 0)
1159 		{
1160 			XNode* bindnode = new XNode(new Tags::BindMaterialTag());
1161 			XNode* techcommmatnode = new XNode(new Tags::TechniqueCommonTag());
1162 			for(unsigned int ii = 0; ii < m.textures.size(); ++ii)
1163 			{
1164 				XNode* instmatnode = new XNode(new Tags::InstanceMaterialTag("material"  + QString::number(ii),"material" + QString::number(ii)));
1165 				XNode* bindvertnode = new XNode(new Tags::BindVertexInputTag("UVSET0","TEXCOORD","0"));
1166 				connectHierarchyNode(techcommmatnode,instmatnode,bindvertnode);
1167 			}
1168 			connectHierarchyNode(visualscenenode,nodenode,instgeonode,bindnode,techcommmatnode);
1169 		}
1170 		else
1171 			connectHierarchyNode(visualscenenode,nodenode,instgeonode);
1172 		libvisualnode->_sons.push_back(visualscenenode);
1173 		root->_sons.push_back(libvisualnode);
1174 
1175 		XNode* scenenode = new XNode(new Tags::SceneTag());
1176 		XNode* instvisualscenenode = new XNode(new Tags::InstanceVisualSceneTag("VisualSceneNode"));
1177 
1178 		scenenode->_sons.push_back(instvisualscenenode);
1179 		root->_sons.push_back(scenenode);
1180 
1181 		return new XMLDocument(root);
1182 	}
1183 
1184 	static void destroyColladaDocument(XMLDocument* doc)
1185 	{
1186 		delete doc;
1187 	}
1188 
1189 	//template<typename MESHMODELTYPE>
1190 	//static int importColladaDocument(const QDomDocument& doc,MESHMODELTYPE& m,const int mask)
1191 	//{
1192 	//	QDomElement root = doc.toElement();
1193 	//	if (root.isNull())
1194 	//		return UtilDAE::E_BAD_CONVERTION_FROM_NODE_TO_ELEMENT;
1195 	//	QDomNodeList lst = root.elementsByTagName("COLLADA");
1196 	//	int err = UtilDAE::checkOccurencies(lst,UtilDAE::ONE);
1197 	//	if (
1198 	//	return vcg::tri::io::UtilDAE::E_NOERROR;
1199 	//}
1200 };
1201 } //Collada
1202 #endif
1203