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