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