Fix for a static variable in BlenderStrokeRenderer::RenderStrokeRep() left after
[blender.git] / source / blender / freestyle / intern / view_map / ViewMapIO.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2010 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/freestyle/intern/view_map/ViewMapIO.cpp
29  *  \ingroup freestyle
30  *  \brief Functions to manage I/O for the view map
31  *  \author Emmanuel Turquin
32  *  \date 09/01/2003
33  */
34
35 #include "ViewMapIO.h"
36
37 #ifdef IRIX
38 #  define WRITE(n) Internal::write<sizeof((n))>(out, (const char *)(&(n)))
39 #  define READ(n) Internal::read<sizeof((n))>(in, (char *)(&(n)))
40 #else
41 #  define WRITE(n) out.write((const char *)(&(n)), sizeof((n)))
42 #  define READ(n) in.read((char *)(&(n)), sizeof((n)))
43 #endif
44
45 #define WRITE_IF_NON_NULL(ptr)  \
46         if (ptr) {                  \
47                 WRITE((ptr)->userdata); \
48         }                           \
49         else {                      \
50                 WRITE(ZERO);            \
51         } (void)0
52
53 #define READ_IF_NON_NULL(ptr, array) \
54         READ(tmp);                       \
55         if (tmp) {                       \
56                 (ptr) = (array)[tmp];        \
57         }                                \
58         else {                           \
59                 (ptr) = NULL;                \
60         } (void)0
61
62 namespace ViewMapIO {
63
64 namespace Internal {
65
66 ViewMap* g_vm;
67
68 //////////////////// 'load' Functions ////////////////////
69
70 inline int load(istream& in, Vec3r& v)
71 {
72         if (Options::getFlags() & Options::FLOAT_VECTORS) {
73                 float tmp;
74                 READ(tmp);
75                 v[0] = tmp;
76                 READ(tmp);
77                 v[1] = tmp;
78                 READ(tmp);
79                 v[2] = tmp;
80         }
81         else {
82                 Vec3r::value_type tmp;
83                 READ(tmp);
84                 v[0] = tmp;
85                 READ(tmp);
86                 v[1] = tmp;
87                 READ(tmp);
88                 v[2] = tmp;
89         }
90         return 0;
91 }
92
93 inline int load(istream& in, Polygon3r& p)
94 {
95         unsigned tmp;
96
97         // Id
98         READ(tmp);
99         p.setId(tmp);
100
101         // vertices (List)
102         vector<Vec3r> tmp_vec;
103         Vec3r v;
104         READ(tmp);
105         for (unsigned int i = 0; i < tmp; i++) {
106                 load(in, v);
107                 tmp_vec.push_back(v);
108         }
109         p.setVertices(tmp_vec);
110
111         // min & max
112         // Already computed (in the SetVertices() method)
113
114         return 0;
115 }
116
117 inline int load(istream& in, FrsMaterial& m)
118 {
119         float tmp_array[4];
120         int i;
121
122         // Diffuse
123         for (i = 0; i < 4; i++)
124                 READ(tmp_array[i]);
125         m.setDiffuse(tmp_array[0], tmp_array[1], tmp_array[2], tmp_array[3]);
126
127         // Specular
128         for (i = 0; i < 4; i++)
129                 READ(tmp_array[i]);
130         m.setSpecular(tmp_array[0], tmp_array[1], tmp_array[2], tmp_array[3]);
131
132         // Ambient
133         for (i = 0; i < 4; i++)
134                 READ(tmp_array[i]);
135         m.setAmbient(tmp_array[0], tmp_array[1], tmp_array[2], tmp_array[3]);
136
137         // Emission
138         for (i = 0; i < 4; i++)
139                 READ(tmp_array[i]);
140         m.setEmission(tmp_array[0], tmp_array[1], tmp_array[2], tmp_array[3]);
141
142         // Shininess
143         READ(tmp_array[0]);
144         m.setShininess(tmp_array[0]);
145
146         return 0;
147 }
148
149 static int load(istream& in, ViewShape *vs)
150 {
151         if (!vs || !vs->sshape())
152                 return 1;
153
154         // SShape
155
156         // -> Id
157         Id::id_type id1, id2;
158         READ(id1);
159         READ(id2);
160         vs->sshape()->setId(Id(id1, id2));
161
162         // -> Importance
163         float importance;
164         READ(importance);
165         vs->sshape()->setImportance(importance);
166
167         // -> BBox
168         //    Not necessary (only used during view map computatiom)
169
170         unsigned i, size, tmp;
171
172         // -> Material
173         READ(size);
174         vector<FrsMaterial> frs_materials;
175         FrsMaterial m;
176         for (i = 0; i < size; ++i) {
177                 load(in, m);
178                 frs_materials.push_back(m);
179         }
180         vs->sshape()->setFrsMaterials(frs_materials);
181
182         // -> VerticesList (List)
183         READ(size);
184         for (i = 0; i < size; i++) {
185                 SVertex *sv;
186                 READ_IF_NON_NULL(sv, g_vm->SVertices());
187                 vs->sshape()->AddNewVertex(sv);
188         }
189
190         // -> Chains (List)
191         READ(size);
192         for (i = 0; i < size; i++) {
193                 FEdge *fe;
194                 READ_IF_NON_NULL(fe, g_vm->FEdges());
195                 vs->sshape()->AddChain(fe);
196         }
197
198         // -> EdgesList (List)
199         READ(size);
200         for (i = 0; i < size; i++) {
201                 FEdge *fe;
202                 READ_IF_NON_NULL(fe, g_vm->FEdges());
203                 vs->sshape()->AddEdge(fe);
204         }
205
206         // ViewEdges (List)
207         READ(size);
208         for (i = 0; i < size; i++) {
209                 ViewEdge *ve;
210                 READ_IF_NON_NULL(ve, g_vm->ViewEdges());
211                 vs->AddEdge(ve);
212         }
213
214         // ViewVertices (List)
215         READ(size);
216         for (i = 0; i < size; i++) {
217                 ViewVertex *vv;
218                 READ_IF_NON_NULL(vv, g_vm->ViewVertices());
219                 vs->AddVertex(vv);
220         }
221
222         return 0;
223 }
224
225
226 static int load(istream& in, FEdge *fe)
227 {
228         if (!fe)
229                 return 1;
230
231         bool b;
232
233         FEdgeSmooth *fesmooth = NULL;
234         FEdgeSharp *fesharp = NULL;
235         if (fe->isSmooth()) {
236                 fesmooth = dynamic_cast<FEdgeSmooth*>(fe);
237         }
238         else {
239                 fesharp = dynamic_cast<FEdgeSharp*>(fe);
240         }
241
242         // Id
243         Id::id_type id1, id2;
244         READ(id1);
245         READ(id2);
246         fe->setId(Id(id1, id2));
247
248         // Nature
249         Nature::EdgeNature nature;
250         READ(nature);
251         fe->setNature(nature);
252
253 #if 0 // hasVisibilityPoint
254         bool b;
255         READ(b);
256         fe->setHasVisibilityPoint(b);
257 #endif
258
259         Vec3r v;
260         unsigned int matindex;
261
262 #if 0
263         // VisibilityPointA
264         load(in, v);
265         fe->setVisibilityPointA(v);
266
267         // VisibilityPointB
268         load(in, v);
269         fe->setVisibilityPointB(v);
270 #endif
271
272         if (fe->isSmooth()) {
273                 // Normal
274                 load(in, v);
275                 fesmooth->setNormal(v);
276
277                 // Material
278                 READ(matindex);
279                 fesmooth->setFrsMaterialIndex(matindex);
280         }
281         else {
282                 // aNormal
283                 load(in, v);
284                 fesharp->setNormalA(v);
285
286                 // bNormal
287                 load(in, v);
288                 fesharp->setNormalB(v);
289
290                 // Materials 
291                 READ(matindex);
292                 fesharp->setaFrsMaterialIndex(matindex);
293                 READ(matindex);
294                 fesharp->setbFrsMaterialIndex(matindex);
295         }
296
297         unsigned tmp;
298
299         // VertexA
300         SVertex *sva;
301         READ_IF_NON_NULL(sva, g_vm->SVertices());
302         fe->setVertexA(sva);
303
304         // VertexB
305         SVertex *svb;
306         READ_IF_NON_NULL(svb, g_vm->SVertices());
307         fe->setVertexB(svb);
308
309         // NextEdge
310         FEdge *nfe;
311         READ_IF_NON_NULL(nfe, g_vm->FEdges());
312         fe->setNextEdge(nfe);
313
314         // PreviousEdge
315         FEdge *pfe;
316         READ_IF_NON_NULL(pfe, g_vm->FEdges());
317         fe->setPreviousEdge(pfe);
318
319         // ViewEdge
320         ViewEdge *ve;
321         READ_IF_NON_NULL(ve, g_vm->ViewEdges());
322         fe->setViewEdge(ve);
323
324         // Face
325         // Not necessary (only used during view map computatiom)
326
327         Polygon3r p;
328
329         // aFace
330         load(in, p);
331         fe->setaFace(p);
332
333         // occludeeEmpty
334         READ(b);
335         fe->setOccludeeEmpty(b);
336
337         // occludeeIntersection
338         load(in, v);
339         fe->setOccludeeIntersection(v);
340
341         return 0;
342 }
343
344 static int load(istream& in, SVertex *sv)
345 {
346         if (!sv)
347                 return 1;
348
349         // Id
350         Id::id_type id1, id2;
351         READ(id1);
352         READ(id2);
353         sv->setId(Id(id1, id2));
354
355         Vec3r v;
356
357         // Point3D
358         load(in, v);
359         sv->setPoint3D(v);
360
361         // Point2D
362         load(in, v);
363         sv->setPoint2D(v);
364
365         unsigned tmp;
366
367         // Shape
368         ViewShape *vs;
369         READ_IF_NON_NULL(vs, g_vm->ViewShapes());
370         sv->setShape(vs->sshape());
371
372         // pViewVertex
373         ViewVertex *vv;
374         READ_IF_NON_NULL(vv, g_vm->ViewVertices());
375         sv->setViewVertex(vv);
376
377         unsigned i, size;
378
379         // Normals (List)
380         READ(size);
381         for (i = 0; i < size; i++) {
382                 load(in, v);
383                 sv->AddNormal(v);
384         }
385
386         // FEdges (List)
387         READ(size);
388         FEdge *fe;
389         for (i = 0; i < size; i++) {
390                 READ_IF_NON_NULL(fe, g_vm->FEdges());
391                 sv->AddFEdge(fe);
392         }
393
394         return 0;
395 }
396
397
398 static int load(istream& in, ViewEdge *ve)
399 {
400         if (!ve)
401                 return 1;
402
403         unsigned tmp;
404
405         // Id
406         Id::id_type id1, id2;
407         READ(id1);
408         READ(id2);
409         ve->setId(Id(id1, id2));
410
411         // Nature
412         Nature::EdgeNature nature;
413         READ(nature);
414         ve->setNature(nature);
415
416         // QI
417         READ(tmp);
418         ve->setQI(tmp);
419
420         // Shape
421         ViewShape *vs;
422         READ_IF_NON_NULL(vs, g_vm->ViewShapes());
423         ve->setShape(vs);
424
425         // aShape
426         ViewShape *avs;
427         READ_IF_NON_NULL(avs, g_vm->ViewShapes());
428         ve->setaShape(avs);
429
430         // FEdgeA
431         FEdge *fea;
432         READ_IF_NON_NULL(fea, g_vm->FEdges());
433         ve->setFEdgeA(fea);
434
435         // FEdgeB
436         FEdge *feb;
437         READ_IF_NON_NULL(feb, g_vm->FEdges());
438         ve->setFEdgeB(feb);
439
440         // A
441         ViewVertex *vva;
442         READ_IF_NON_NULL(vva, g_vm->ViewVertices());
443         ve->setA(vva);
444
445         // B
446         ViewVertex *vvb;
447         READ_IF_NON_NULL(vvb, g_vm->ViewVertices());
448         ve->setB(vvb);
449
450         // Occluders (List)
451         if (!(Options::getFlags() & Options::NO_OCCLUDERS)) {
452                 unsigned size;
453                 READ(size);
454                 ViewShape *vso;
455                 for (unsigned int i = 0; i < size; i++) {
456                         READ_IF_NON_NULL(vso, g_vm->ViewShapes());
457                         ve->AddOccluder(vso);
458                 }
459         }
460
461         return 0;
462 }
463
464
465 static int load(istream& in, ViewVertex *vv)
466 {
467         if (!vv)
468                 return 1;
469
470         unsigned tmp;
471         bool b;
472
473         // Nature
474         Nature::VertexNature nature;
475         READ(nature);
476         vv->setNature(nature);
477
478         if (vv->getNature() & Nature::T_VERTEX) {
479                 TVertex *tv = dynamic_cast<TVertex*>(vv);
480
481                 // Id
482                 Id::id_type id1, id2;
483                 READ(id1);
484                 READ(id2);
485                 tv->setId(Id(id1, id2));
486
487                 // FrontSVertex
488                 SVertex *fsv;
489                 READ_IF_NON_NULL(fsv, g_vm->SVertices());
490                 tv->setFrontSVertex(fsv);
491
492                 // BackSVertex
493                 SVertex *bsv;
494                 READ_IF_NON_NULL(bsv, g_vm->SVertices());
495                 tv->setBackSVertex(bsv);
496
497                 // FrontEdgeA
498                 ViewEdge *fea;
499                 READ_IF_NON_NULL(fea, g_vm->ViewEdges());
500                 READ(b);
501                 tv->setFrontEdgeA(fea, b);
502
503                 // FrontEdgeB
504                 ViewEdge *feb;
505                 READ_IF_NON_NULL(feb, g_vm->ViewEdges());
506                 READ(b);
507                 tv->setFrontEdgeB(feb, b);
508
509                 // BackEdgeA
510                 ViewEdge *bea;
511                 READ_IF_NON_NULL(bea, g_vm->ViewEdges());
512                 READ(b);
513                 tv->setBackEdgeA(bea, b);
514
515                 // BackEdgeB
516                 ViewEdge *beb;
517                 READ_IF_NON_NULL(beb, g_vm->ViewEdges());
518                 READ(b);
519                 tv->setBackEdgeB(beb, b);
520         }
521         else if (vv->getNature() & Nature::NON_T_VERTEX) {
522                 NonTVertex *ntv = dynamic_cast<NonTVertex*>(vv);
523
524                 // SVertex
525                 SVertex *sv;
526                 READ_IF_NON_NULL(sv, g_vm->SVertices());
527                 ntv->setSVertex(sv);
528
529                 // ViewEdges (List)
530                 unsigned size;
531                 READ(size);
532                 ViewEdge *ve;
533                 for (unsigned int i = 0; i < size; i++) {
534                         READ_IF_NON_NULL(ve, g_vm->ViewEdges());
535                         READ(b);
536                         ntv->AddViewEdge(ve, b);
537                 }
538         }
539
540         return 0;
541 }
542
543 //////////////////// 'save' Functions ////////////////////
544
545 inline int save(ostream& out, const Vec3r& v)
546 {
547         if (Options::getFlags() & Options::FLOAT_VECTORS) {
548                 float tmp;
549
550                 tmp = v[0];
551                 WRITE(tmp);
552                 tmp = v[1];
553                 WRITE(tmp);
554                 tmp = v[2];
555                 WRITE(tmp);
556         }
557         else {
558                 Vec3r::value_type tmp;
559
560                 tmp = v[0];
561                 WRITE(tmp);
562                 tmp = v[1];
563                 WRITE(tmp);
564                 tmp = v[2];
565                 WRITE(tmp);
566         }
567         return 0;
568 }
569
570
571 inline int save(ostream& out, const Polygon3r& p)
572 {
573         unsigned tmp;
574
575         // Id
576         tmp = p.getId();
577         WRITE(tmp);
578
579         // vertices (List)
580         tmp = p.getVertices().size();
581         WRITE(tmp);
582         for (vector<Vec3r>::const_iterator i = p.getVertices().begin(); i != p.getVertices().end(); i++) {
583                 save(out, *i);
584         }
585
586         // min & max
587         // Do not need to be saved
588
589         return 0;
590 }
591
592 inline int save(ostream& out, const FrsMaterial& m)
593 {
594         unsigned i;
595
596         // Diffuse
597         for (i = 0; i < 4; i++)
598                 WRITE(m.diffuse()[i]);
599
600         // Specular
601         for (i = 0; i < 4; i++)
602                 WRITE(m.specular()[i]);
603
604         // Ambient
605         for (i = 0; i < 4; i++)
606                 WRITE(m.ambient()[i]);
607
608         // Emission
609         for (i = 0; i < 4; i++)
610                 WRITE(m.emission()[i]);
611
612         // Shininess
613         float shininess = m.shininess();
614         WRITE(shininess);
615
616         return 0;
617 }
618
619 static int save(ostream& out, ViewShape *vs)
620 {
621         if (!vs || !vs->sshape()) {
622                 cerr << "Warning: null ViewShape" << endl;
623                 return 1;
624         }
625
626         unsigned tmp;
627
628         // SShape
629
630         // -> Id
631         Id::id_type id = vs->sshape()->getId().getFirst();
632         WRITE(id);
633         id = vs->sshape()->getId().getSecond();
634         WRITE(id);
635
636         // -> Importance
637         float importance = vs->sshape()->importance();
638         WRITE(importance);
639
640         // -> BBox
641         //    Not necessary (only used during view map computatiom)
642
643         // -> Material
644         unsigned int size = vs->sshape()->frs_materials().size();
645         WRITE(size);
646         for (unsigned int i = 0; i < size; ++i)
647                 save(out, vs->sshape()->frs_material(i));
648
649         // -> VerticesList (List)
650         tmp = vs->sshape()->getVertexList().size();
651         WRITE(tmp);
652         for (vector<SVertex*>::const_iterator i1 = vs->sshape()->getVertexList().begin();
653              i1 != vs->sshape()->getVertexList().end();
654              i1++)
655         {
656                 WRITE_IF_NON_NULL(*i1);
657         }
658
659         // -> Chains (List)
660         tmp = vs->sshape()->getChains().size();
661         WRITE(tmp);
662         for (vector<FEdge*>::const_iterator i2 = vs->sshape()->getChains().begin();
663              i2 != vs->sshape()->getChains().end();
664              i2++)
665         {
666                 WRITE_IF_NON_NULL(*i2);
667         }
668
669         // -> EdgesList (List)
670         tmp = vs->sshape()->getEdgeList().size();
671         WRITE(tmp);
672         for (vector<FEdge*>::const_iterator i3 = vs->sshape()->getEdgeList().begin();
673              i3 != vs->sshape()->getEdgeList().end();
674              i3++)
675         {
676                 WRITE_IF_NON_NULL(*i3);
677         }
678
679         // ViewEdges (List)
680         tmp = vs->edges().size();
681         WRITE(tmp);
682         for (vector<ViewEdge*>::const_iterator i4 = vs->edges().begin(); i4 != vs->edges().end(); i4++)
683                 WRITE_IF_NON_NULL(*i4);
684
685         // ViewVertices (List)
686         tmp = vs->vertices().size();
687         WRITE(tmp);
688         for (vector<ViewVertex*>::const_iterator i5 = vs->vertices().begin(); i5 != vs->vertices().end(); i5++)
689                 WRITE_IF_NON_NULL(*i5);
690
691         return 0;
692 }
693
694
695 static int save(ostream& out, FEdge *fe)
696 {
697         if (!fe) {
698                 cerr << "Warning: null FEdge" << endl;
699                 return 1;
700         }
701
702         FEdgeSmooth *fesmooth = dynamic_cast<FEdgeSmooth*>(fe);
703         FEdgeSharp *fesharp =  dynamic_cast<FEdgeSharp*>(fe);
704
705         // Id
706         Id::id_type id = fe->getId().getFirst();
707         WRITE(id);
708         id = fe->getId().getSecond();
709         WRITE(id);
710
711         // Nature
712         Nature::EdgeNature nature = fe->getNature();
713         WRITE(nature);
714
715         bool b;
716
717 #if 0
718         // hasVisibilityPoint
719         b = fe->hasVisibilityPoint();
720         WRITE(b);
721
722         // VisibilityPointA
723         save(out, fe->visibilityPointA());
724
725         // VisibilityPointB
726         save(out, fe->visibilityPointB());
727 #endif
728
729         unsigned index;
730         if (fe->isSmooth()) {
731                 // normal
732                 save(out, fesmooth->normal());
733                 // material
734                 index = fesmooth->frs_materialIndex();
735                 WRITE(index);
736         }
737         else {
738                 // aNormal
739                 save(out, fesharp->normalA());
740                 // bNormal
741                 save(out, fesharp->normalB());
742                 // aMaterial
743                 index = fesharp->aFrsMaterialIndex();
744                 WRITE(index);
745                 // bMaterial
746                 index = fesharp->bFrsMaterialIndex();
747                 WRITE(index);
748         }
749
750         // VertexA
751         WRITE_IF_NON_NULL(fe->vertexA());
752
753         // VertexB
754         WRITE_IF_NON_NULL(fe->vertexB());
755
756         // NextEdge
757         WRITE_IF_NON_NULL(fe->nextEdge());
758
759         // PreviousEdge
760         WRITE_IF_NON_NULL(fe->previousEdge());
761
762         // ViewEdge
763         WRITE_IF_NON_NULL(fe->viewedge());
764
765         // Face
766         // Not necessary (only used during view map computatiom)
767
768         // aFace
769         save(out, (Polygon3r&)fe->aFace());
770
771         // occludeeEmpty
772         b = fe->getOccludeeEmpty();
773         WRITE(b);
774
775         // occludeeIntersection
776         save(out, fe->getOccludeeIntersection());
777
778         return 0;
779 }
780
781 static int save(ostream& out, SVertex *sv)
782 {
783         if (!sv) {
784                 cerr << "Warning: null SVertex" << endl;
785                 return 1;
786         }
787
788         unsigned tmp;
789
790         // Id
791         Id::id_type id = sv->getId().getFirst();
792         WRITE(id);
793         id = sv->getId().getSecond();
794         WRITE(id);
795
796         Vec3r v;
797
798         // Point3D
799         v = sv->point3D();
800         save(out, sv->point3D());
801
802         // Point2D
803         v = sv->point2D();
804         save(out, v);
805
806         // Shape
807         WRITE_IF_NON_NULL(sv->shape());
808
809         // pViewVertex
810         WRITE_IF_NON_NULL(sv->viewvertex());
811
812         // Normals (List)
813         // Note: the 'size()' method of a set doesn't seem to return the actual size of the given set, so we have to
814         // hack it...
815         set<Vec3r>::const_iterator i;
816         for (i = sv->normals().begin(), tmp = 0; i != sv->normals().end(); i++, tmp++);
817         WRITE(tmp);
818         for (i = sv->normals().begin(); i != sv->normals().end(); i++)
819                 save(out, *i);
820
821         // FEdges (List)
822         tmp = sv->fedges().size();
823         WRITE(tmp);
824         for (vector<FEdge*>::const_iterator j = sv->fedges_begin(); j != sv->fedges_end(); j++)
825                 WRITE_IF_NON_NULL(*j);
826
827         return 0;
828 }
829
830
831 static int save(ostream& out, ViewEdge *ve)
832 {
833         if (!ve) {
834                 cerr << "Warning: null ViewEdge" << endl;
835                 return 1;
836         }
837
838         unsigned tmp;
839
840         // Id
841         Id::id_type id = ve->getId().getFirst();
842         WRITE(id);
843         id = ve->getId().getSecond();
844         WRITE(id);
845
846         // Nature
847         Nature::EdgeNature nature = ve->getNature();
848         WRITE(nature);
849
850         // QI
851         unsigned qi = ve->qi();
852         WRITE(qi);
853
854         // Shape
855         WRITE_IF_NON_NULL(ve->shape());
856
857         // aShape
858         WRITE_IF_NON_NULL(ve->aShape());
859
860         // FEdgeA
861         WRITE_IF_NON_NULL(ve->fedgeA());
862
863         // FEdgeB
864         WRITE_IF_NON_NULL(ve->fedgeB());
865
866         // A
867         WRITE_IF_NON_NULL(ve->A());
868
869         // B
870         WRITE_IF_NON_NULL(ve->B());
871
872         // Occluders (List)
873         if (!(Options::getFlags() & Options::NO_OCCLUDERS)) {
874                 tmp = ve->occluders().size();
875                 WRITE(tmp);
876                 for (vector<ViewShape*>::const_iterator i = ve->occluders().begin(); i != ve->occluders().end(); i++)
877                         WRITE_IF_NON_NULL((*i));
878         }
879
880         return 0;
881 }
882
883
884 static int save(ostream& out, ViewVertex *vv)
885 {
886         if (!vv) {
887                 cerr << "Warning: null ViewVertex" << endl;
888                 return 1;
889         }
890
891         // Nature
892         Nature::VertexNature nature = vv->getNature();
893         WRITE(nature);
894
895         if (vv->getNature() & Nature::T_VERTEX) {
896                 TVertex *tv = dynamic_cast<TVertex*>(vv);
897
898                 // Id
899                 Id::id_type id = tv->getId().getFirst();
900                 WRITE(id);
901                 id = tv->getId().getSecond();
902                 WRITE(id);
903
904                 // FrontSVertex
905                 WRITE_IF_NON_NULL(tv->frontSVertex());
906
907                 // BackSVertex
908                 WRITE_IF_NON_NULL(tv->backSVertex());
909
910                 // FrontEdgeA
911                 WRITE_IF_NON_NULL(tv->frontEdgeA().first);
912                 WRITE(tv->frontEdgeA().second);
913
914                 // FrontEdgeB
915                 WRITE_IF_NON_NULL(tv->frontEdgeB().first);
916                 WRITE(tv->frontEdgeB().second);
917
918                 // BackEdgeA
919                 WRITE_IF_NON_NULL(tv->backEdgeA().first);
920                 WRITE(tv->backEdgeA().second);
921
922                 // BackEdgeB
923                 WRITE_IF_NON_NULL(tv->backEdgeB().first);
924                 WRITE(tv->backEdgeB().second);
925         }
926         else if (vv->getNature() & Nature::NON_T_VERTEX) {
927                 NonTVertex *ntv = dynamic_cast<NonTVertex*>(vv);
928
929                 // SVertex
930                 WRITE_IF_NON_NULL(ntv->svertex());
931
932                 // ViewEdges (List)
933                 unsigned size = ntv->viewedges().size();
934                 WRITE(size);
935                 vector<ViewVertex::directedViewEdge>::const_iterator i = ntv->viewedges().begin();
936                 for (; i != ntv->viewedges().end(); i++) {
937                         WRITE_IF_NON_NULL(i->first);
938                         WRITE(i->second);
939                 }
940         }
941         else {
942                 cerr << "Warning: unexpected ViewVertex nature" << endl;
943                 return 1;
944         }
945
946         return 0;
947 }
948
949 } // End of namespace Internal
950
951
952 //////////////////// "Public" 'load' and 'save' functions ////////////////////
953
954 #define SET_PROGRESS(n)       \
955         if (pb) {                 \
956                 pb->setProgress((n)); \
957         } (void)0
958
959 int load(istream& in, ViewMap *vm, ProgressBar *pb)
960 {
961         if (!vm)
962                 return 1;
963
964         //soc unused - unsigned tmp;
965         int err = 0;
966         Internal::g_vm = vm;
967
968         // Management of the progress bar (if present)
969         if (pb) {
970                 pb->reset();
971                 pb->setLabelText("Loading View Map...");
972                 pb->setTotalSteps(6);
973                 pb->setProgress(0);
974         }
975
976         // Read and set the options
977         unsigned char flags;
978         READ(flags);
979         Options::setFlags(flags);
980
981         // Read the size of the five ViewMap's lists (with some extra informations for the ViewVertices)
982         // and instantiate them (with default costructors)
983         unsigned vs_s, fe_s, fe_rle1, fe_rle2, sv_s, ve_s, vv_s, vv_rle1, vv_rle2;
984         READ(vs_s);
985         READ(fe_s);
986
987         if (fe_s) {
988                 bool b;
989                 READ(b);
990                 for (READ(fe_rle1), fe_rle2 = 0; fe_rle1 < fe_s + 1; fe_rle2 = fe_rle1, READ(fe_rle1)) {
991                         if (b) {
992                                 for (unsigned int i = fe_rle2; i < fe_rle1; i++) {
993                                         FEdgeSmooth *fes = new FEdgeSmooth;
994                                         vm->AddFEdge(fes);
995                                 }
996                                 b = !b;
997                         }
998                         else if (!b) {
999                                 for (unsigned int i = fe_rle2; i < fe_rle1; i++) {
1000                                         FEdgeSharp *fes = new FEdgeSharp;
1001                                         vm->AddFEdge(fes);
1002                                 }
1003                                 b = !b;
1004                         }
1005                 }
1006         }
1007
1008         READ(sv_s);
1009         READ(ve_s);
1010         READ(vv_s);
1011
1012         if (vv_s) {
1013                 Nature::VertexNature nature;
1014                 READ(nature);
1015                 for (READ(vv_rle1), vv_rle2 = 0; vv_rle1 < vv_s + 1; vv_rle2 = vv_rle1, READ(vv_rle1)) {
1016                         if (nature & Nature::T_VERTEX) {
1017                                 for (unsigned int i = vv_rle2; i < vv_rle1; i++) {
1018                                         TVertex *tv = new TVertex();
1019                                         vm->AddViewVertex(tv);
1020                                 }
1021                                 nature = Nature::NON_T_VERTEX;
1022                         }
1023                         else if (nature & Nature::NON_T_VERTEX) {
1024                                 for (unsigned int i = vv_rle2; i < vv_rle1; i++) {
1025                                         NonTVertex *ntv = new NonTVertex();
1026                                         vm->AddViewVertex(ntv);
1027                                 }
1028                                 nature = Nature::T_VERTEX;
1029                         }
1030                 }
1031         }
1032
1033         for (unsigned int i0 = 0; i0 < vs_s; i0++) {
1034                 SShape *ss = new SShape();
1035                 ViewShape *vs = new ViewShape();
1036                 vs->setSShape(ss);
1037                 ss->setViewShape(vs);
1038                 vm->AddViewShape(vs);
1039         }
1040 #if 0
1041         for (unsigned int i1 = 0; i1 < fe_s; i1++) {
1042                 FEdge *fe = new FEdge();
1043                 vm->AddFEdge(fe);
1044         }
1045 #endif
1046         for (unsigned int i2 = 0; i2 < sv_s; i2++) {
1047                 SVertex *sv = new SVertex();
1048                 vm->AddSVertex(sv);
1049         }
1050         for (unsigned int i3 = 0; i3 < ve_s; i3++) {
1051                 ViewEdge *ve = new ViewEdge();
1052                 vm->AddViewEdge(ve);
1053         }
1054
1055         // Read the values for all the objects created above
1056         SET_PROGRESS(1);
1057         for (vector<ViewShape*>::const_iterator i4 = vm->ViewShapes().begin(); i4 != vm->ViewShapes().end(); i4++)
1058                 err += Internal::load(in, *i4);
1059         SET_PROGRESS(2);
1060         for (vector<FEdge*>::const_iterator i5 = vm->FEdges().begin(); i5 != vm->FEdges().end(); i5++)
1061                 err += Internal::load(in, *i5);
1062         SET_PROGRESS(3);
1063         for (vector<SVertex*>::const_iterator i6 = vm->SVertices().begin(); i6 != vm->SVertices().end(); i6++)
1064                 err += Internal::load(in, *i6);
1065         SET_PROGRESS(4);
1066         for (vector<ViewEdge*>::const_iterator i7 = vm->ViewEdges().begin(); i7 != vm->ViewEdges().end(); i7++)
1067                 err += Internal::load(in, *i7);
1068         SET_PROGRESS(5);
1069         for (vector<ViewVertex*>::const_iterator i8 = vm->ViewVertices().begin(); i8 != vm->ViewVertices().end(); i8++)
1070                 err += Internal::load(in, *i8);
1071         SET_PROGRESS(6);
1072
1073         // Read the shape id to index mapping
1074         unsigned map_s;
1075         READ(map_s);
1076         unsigned id,index;
1077         for (unsigned int i4 = 0; i4 < map_s; ++i4) {
1078                 READ(id);
1079                 READ(index);
1080                 vm->shapeIdToIndexMap()[id] = index;
1081         }
1082
1083         return err;
1084 }
1085
1086
1087 int save(ostream& out, ViewMap *vm, ProgressBar *pb)
1088 {
1089         if (!vm)
1090                 return 1;
1091
1092         int err = 0;
1093
1094         // Management of the progress bar (if present)
1095         if (pb) {
1096                 pb->reset();
1097                 pb->setLabelText("Saving View Map...");
1098                 pb->setTotalSteps(6);
1099                 pb->setProgress(0);
1100         }
1101
1102         // For every object, initialize its userdata member to its index in the ViewMap list
1103         for (unsigned int i0 = 0; i0 < vm->ViewShapes().size(); i0++) {
1104                 vm->ViewShapes()[i0]->userdata = SET_UINT_IN_POINTER(i0);
1105                 vm->ViewShapes()[i0]->sshape()->userdata = SET_UINT_IN_POINTER(i0);
1106         }
1107         for (unsigned int i1 = 0; i1 < vm->FEdges().size(); i1++)
1108                 vm->FEdges()[i1]->userdata = SET_UINT_IN_POINTER(i1);
1109         for (unsigned int i2 = 0; i2 < vm->SVertices().size(); i2++)
1110                 vm->SVertices()[i2]->userdata = SET_UINT_IN_POINTER(i2);
1111         for (unsigned int i3 = 0; i3 < vm->ViewEdges().size(); i3++)
1112                 vm->ViewEdges()[i3]->userdata = SET_UINT_IN_POINTER(i3);
1113         for (unsigned int i4 = 0; i4 < vm->ViewVertices().size(); i4++)
1114                 vm->ViewVertices()[i4]->userdata = SET_UINT_IN_POINTER(i4);
1115
1116         // Write the current options
1117         unsigned char flags = Options::getFlags();
1118         WRITE(flags);
1119
1120         // Write the size of the five lists (with some extra informations for the ViewVertices)
1121         unsigned size;
1122         size = vm->ViewShapes().size();
1123         WRITE(size);
1124         size = vm->FEdges().size();
1125         WRITE(size);
1126         if (size) {
1127                 bool b = vm->FEdges()[0]->isSmooth();
1128                 WRITE(b);
1129                 for (unsigned int i = 0; i < size; i++) {
1130                         while (i < size && (vm->FEdges()[i]->isSmooth() == b))
1131                                 i++;
1132                         if (i < size) {
1133                                 WRITE(i);
1134                                 b = !b;
1135                         }
1136                 }
1137                 WRITE(size);
1138                 size++;
1139                 WRITE(size);
1140         }
1141         size = vm->SVertices().size();
1142         WRITE(size);
1143         size = vm->ViewEdges().size();
1144         WRITE(size);
1145         size = vm->ViewVertices().size();
1146         WRITE(size);
1147         if (size) {
1148                 Nature::VertexNature nature = vm->ViewVertices()[0]->getNature();
1149                 WRITE(nature);
1150                 nature &= ~Nature::VIEW_VERTEX;
1151                 for (unsigned int i = 0; i < size; i++) {
1152                         while (i < size && (vm->ViewVertices()[i]->getNature() & nature))
1153                                 i++;
1154                         if (i < size) {
1155                                 WRITE(i);
1156                                 nature = vm->ViewVertices()[i]->getNature() & ~Nature::VIEW_VERTEX;
1157                         }
1158                 }
1159                 WRITE(size);
1160                 size++;
1161                 WRITE(size);
1162         }
1163
1164         // Write all the elts of the ViewShapes List
1165         SET_PROGRESS(1);
1166         for (vector<ViewShape*>::const_iterator i5 = vm->ViewShapes().begin(); i5 != vm->ViewShapes().end(); i5++)
1167                 err += Internal::save(out, *i5);
1168         SET_PROGRESS(2);
1169         for (vector<FEdge*>::const_iterator i6 = vm->FEdges().begin(); i6 != vm->FEdges().end(); i6++)
1170                 err += Internal::save(out, *i6);
1171         SET_PROGRESS(3);
1172         for (vector<SVertex*>::const_iterator i7 = vm->SVertices().begin(); i7 != vm->SVertices().end(); i7++)
1173                 err += Internal::save(out, *i7);
1174         SET_PROGRESS(4);
1175         for (vector<ViewEdge*>::const_iterator i8 = vm->ViewEdges().begin(); i8 != vm->ViewEdges().end(); i8++)
1176                 err += Internal::save(out, *i8);
1177         SET_PROGRESS(5);
1178         for (vector<ViewVertex*>::const_iterator i9 = vm->ViewVertices().begin(); i9 != vm->ViewVertices().end(); i9++)
1179                 err += Internal::save(out, *i9);
1180
1181         // Write the shape id to index mapping
1182         size = vm->shapeIdToIndexMap().size();
1183         WRITE(size);
1184         unsigned int id, index;
1185         for (ViewMap::id_to_index_map::iterator mit = vm->shapeIdToIndexMap().begin(),
1186                                                 mitend = vm->shapeIdToIndexMap().end();
1187              mit != mitend;
1188              ++mit)
1189         {
1190                 id = mit->first;
1191                 index = mit->second;
1192                 WRITE(id);
1193                 WRITE(index);
1194         }
1195
1196         // Reset 'userdata' members
1197         for (vector<ViewShape*>::const_iterator j0 = vm->ViewShapes().begin(); j0 != vm->ViewShapes().end(); j0++) {
1198                 (*j0)->userdata = NULL;
1199                 (*j0)->sshape()->userdata = NULL;
1200         }
1201         for (vector<FEdge*>::const_iterator j1 = vm->FEdges().begin(); j1 != vm->FEdges().end(); j1++)
1202                 (*j1)->userdata = NULL;
1203         for (vector<SVertex*>::const_iterator j2 = vm->SVertices().begin(); j2 != vm->SVertices().end(); j2++)
1204                 (*j2)->userdata = NULL;
1205         for (vector<ViewEdge*>::const_iterator j3 = vm->ViewEdges().begin(); j3 != vm->ViewEdges().end(); j3++)
1206                 (*j3)->userdata = NULL;
1207         for (vector<ViewVertex*>::const_iterator j4 = vm->ViewVertices().begin(); j4 != vm->ViewVertices().end(); j4++)
1208                 (*j4)->userdata = NULL;
1209         SET_PROGRESS(6);
1210
1211         return err;
1212 }
1213
1214
1215 //////////////////// Options ////////////////////
1216
1217 namespace Options {
1218
1219 namespace Internal {
1220
1221 static unsigned char g_flags = 0;
1222 static string g_models_path;
1223
1224 } // End of namespace Internal
1225
1226 void setFlags(const unsigned char flags)
1227 {
1228         Internal::g_flags = flags;
1229 }
1230
1231 void addFlags(const unsigned char flags)
1232 {
1233         Internal::g_flags |= flags;
1234 }
1235
1236 void rmFlags(const unsigned char flags)
1237 {
1238         Internal::g_flags &= ~flags;
1239 }
1240
1241 unsigned char getFlags()
1242 {
1243         return Internal::g_flags;
1244 }
1245
1246 void setModelsPath(const string& path)
1247 {
1248         Internal::g_models_path = path;
1249 }
1250
1251 string getModelsPath()
1252 {
1253         return Internal::g_models_path;
1254 }
1255
1256 } // End of namepace Options
1257
1258 } // End of namespace ViewMapIO