1 #ifndef __VCGLIB_EXPORT_RIB
2 #define __VCGLIB_EXPORT_RIB
3 
4 #define RIB_EXPORT_STEPS 7
5 
6 #include<wrap/io_trimesh/io_mask.h>
7 #include<wrap/callback.h>
8 #include<vcg/complex/algorithms/clean.h>
9 
10 
11 #include <stdio.h>
12 #include <QTime>
13 
14 namespace vcg {
15 namespace tri {
16 namespace io {
17 
18 
19 template <class SaveMeshType>
20 class ExporterRIB
21 {
22 
23 public:
24 typedef typename SaveMeshType::VertexPointer VertexPointer;
25 typedef typename SaveMeshType::ScalarType ScalarType;
26 typedef typename SaveMeshType::VertexType VertexType;
27 typedef typename SaveMeshType::FaceType FaceType;
28 typedef typename SaveMeshType::FacePointer FacePointer;
29 typedef typename SaveMeshType::VertexIterator VertexIterator;
30 typedef typename SaveMeshType::FaceIterator FaceIterator;
31 
32 static int Save(SaveMeshType &m,  const char * filename, bool binary, CallBackPos *cb=0) {
33   return Save(m,filename, Mask::IOM_ALL, binary, cb);
34 }
35 
36 static int Save(SaveMeshType &mm,  const char * filename, int savemask, bool /*binary*/, CallBackPos *cb=0)
37 {
38   //ignore binary for now!
39 
40   //working with a copy of mesh
41   SaveMeshType &m = mm;
42 
43   int cbStep = 100/RIB_EXPORT_STEPS, cbValue = 0, step = 0;
44   if(*cb != 0) cb(cbValue, "Start exporting");
45 
46   FILE *fout = fopen(filename,"wb");
47   if(fout==NULL) {
48     return E_CANTOPEN;
49   }
50 
51   QTime tt; tt.start(); //debug
52 
53   fprintf(fout,"#generated by VCGLIB\n"); //commento d'intestazione????
54 
55   //initial declaring
56   if(m.HasPerVertexColor() && (savemask & Mask::IOM_VERTCOLOR))
57     fprintf(fout,"Declare \"Cs\" \"facevarying color\"\n");
58 
59   if((HasPerVertexTexCoord(m) && (savemask & Mask::IOM_VERTTEXCOORD)) ||
60 	  (HasPerWedgeTexCoord(m) && (savemask & Mask::IOM_WEDGTEXCOORD)))
61     fprintf(fout,"Declare \"st\" \"facevarying float[2]\"\n");
62 
63   if(HasPerVertexNormal(m) && (savemask & Mask::IOM_VERTNORMAL))
64     fprintf(fout,"Declare \"N\" \"facevarying normal\"\n");
65 
66   if(HasPerVertexQuality(m) && (savemask & Mask::IOM_VERTQUALITY))
67     fprintf(fout,"Declare \"Q\" \"facevarying float\"\n");
68 
69   tri::Clean<SaveMeshType>::RemoveUnreferencedVertex(m);
70   Allocator<SaveMeshType>::CompactVertexVector(m);
71   Allocator<SaveMeshType>::CompactFaceVector(m);
72 
73   //first step: faces topology
74   fprintf(fout,"PointsPolygons\n[\n");
75   int incr = m.fn/cbStep, i=0;
76   for(i=0; i<m.fn; i++) {
77     fprintf(fout,"3 ");//\n");
78   	if((*cb != 0) && i%incr == 0) cb(++cbValue, "Exporting face topology");
79   }
80   fprintf(fout,"\n");
81   fprintf(fout,"]\n[\n");
82   qDebug("PointsPolygons %i",tt.elapsed());
83   cbValue = (++step)*cbStep; i=0;
84 
85   //second step: index of vertex for face
86   UpdateFlags<SaveMeshType>::VertexClearV(m);
87   for(FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi, ++i) {
88 	  if((*cb != 0) && i%incr == 0) cb(++cbValue, "Exporting index of verteces");
89     for(int j=0; j<3; ++j) {
90       int indexOfVertex = (*fi).V(j) - &(m.vert[0]);
91 	    fprintf(fout,"%i ",indexOfVertex);
92 	    //if it's the first visit, set visited bit
93 	    if(!(*fi).V(j)->IsV()) {
94 		    (*fi).V(j)->SetV();
95 	    }
96 	  }
97 	  //fprintf(fout,"\n");
98 	  fprintf(fout," ");
99   }
100   fprintf(fout,"\n]\n");
101   qDebug("coords %i",tt.elapsed());
102   cbValue = (++step)*cbStep; i=0;
103 
104   //third step: vertex coordinates
105   fprintf(fout,"\"P\"\n[\n");
106   Matrix44f mat = Matrix44f::Identity();
107   mat = mat.SetScale(1.0,1.0,1.0);
108   incr = m.vn/cbStep;
109   for(VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi, ++i) {
110     if((*cb != 0) && i%incr == 0) cb(++cbValue, "Exporting vertex coordinates");
111     if(vi->IsV()) {
112 	    Point3f p = mat * vi->P();
113 	    fprintf(fout,"%g %g %g ",p[0],p[1],p[2]);
114 	  }
115   }
116   fprintf(fout,"\n]\n");
117   qDebug("coords %i",tt.elapsed());
118 
119   incr = m.fn/cbStep; cbValue = (++step)*cbStep; i=0;
120   //fourth step: vertex normal
121   if(HasPerVertexNormal(m) && (savemask & Mask::IOM_VERTNORMAL)) {
122     fprintf(fout,"\"N\"\n[\n");
123     for(FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi, ++i) {
124 	    if((*cb != 0) && i%incr == 0) cb(++cbValue, "Exporting vertex normals");
125 	    //for each face, foreach vertex write normal
126 	    for(int j=0; j<3; ++j) {
127         Point3f n = mat * (*fi).V(j)->N(); //transform normal too
128         fprintf(fout,"%g %g %g ",n[0],n[1],n[2]);
129 	    }
130 	  }
131 	  fprintf(fout,"\n]\n");
132 	  qDebug("normal %i",tt.elapsed());
133   }
134   cbValue = (++step)*cbStep; i=0;
135 
136   //fifth step: vertex color (ignore face color?)
137   if(m.HasPerVertexColor() && (savemask & Mask::IOM_VERTCOLOR)) {
138     fprintf(fout,"\"Cs\"\n[\n");
139 	  for(FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi, ++i) {
140 	    if((*cb != 0) && i%incr == 0) cb(++cbValue, "Exporting vertex colors");
141 	    //for each face, foreach vertex write color
142 	    for(int j=0; j<3; ++j) {
143 	      Color4b &c=(*fi).V(j)->C();
144     		fprintf(fout,"%g %g %g ",float(c[0])/255,float(c[1])/255,float(c[2])/255);
145    	  }
146 	  }
147 	  fprintf(fout,"\n]\n");
148 	  qDebug("color %i",tt.elapsed());
149   }
150   cbValue = (++step)*cbStep; i=0;
151 
152   //sixth step: texture coordinates (for edge)
153   if((HasPerVertexTexCoord(m) && (savemask & Mask::IOM_VERTTEXCOORD)) ||
154 	  (HasPerWedgeTexCoord(m) && (savemask & Mask::IOM_WEDGTEXCOORD))) {
155   	fprintf(fout,"\"st\"\n[\n"); i=0;
156 	  for(FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi, ++i) {
157       if((*cb != 0) && i%incr == 0) cb(++cbValue, "Exporting vertex/edge texture coordinates");
158 	    //for each face, foreach vertex write uv coord
159 	    for(int j=0; j<3; ++j) {
160 	      fprintf(fout,"%g %g ",(*fi).WT(j).U() , 1.0 - (*fi).WT(j).V()); //v origin axis is up
161 	    }
162 	  }
163 	  fprintf(fout,"\n]\n");
164 	  qDebug("texcoords %i",tt.elapsed());
165   }
166   cbValue = (++step)*cbStep; i=0;
167 
168   //seventh step: vertex quality
169   if(HasPerVertexQuality(m) && (savemask & Mask::IOM_VERTQUALITY)) {
170 	  fprintf(fout,"\"Q\"\n[\n"); i=0;
171 	  for(FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi, ++i) {
172 	    if((*cb != 0) && i%incr == 0) cb(++cbValue, "Exporting vertex quality");
173 	    //for each face, foreach vertex write its quality
174 	    for(int j=0; j<3; ++j) {
175 	      fprintf(fout,"%g ",(*fi).V(j)->Q());
176   	  }
177   	}
178   	fprintf(fout,"\n]\n");
179   	qDebug("quality %i",tt.elapsed());
180   }
181   cb(100, "Exporting completed");
182   fclose(fout);
183 
184   return E_NOERROR;
185 }
186 
187 enum RibError {
188   E_NOERROR,				// 0
189 		// Errors of  open(..)
190 	E_CANTOPEN,				// 1
191 	E_MAXRIBERRORS
192 };
193 
ErrorMsg(int error)194 static const char *ErrorMsg(int error) {
195   static std::vector<std::string> rib_error_msg;
196   if(rib_error_msg.empty())
197   {
198     rib_error_msg.resize(E_MAXRIBERRORS);
199     rib_error_msg[E_NOERROR		]="No errors";
200 	  rib_error_msg[E_CANTOPEN  ]="Can't open file";
201   }
202 
203   if(error > E_MAXRIBERRORS || error < 0)
204     return "Unknown error";
205   else
206     return rib_error_msg[error].c_str();
207 };
208 
GetExportMaskCapability()209  static int GetExportMaskCapability() {
210 	  int capability = 0;
211 	  capability |= vcg::tri::io::Mask::IOM_VERTCOORD    ;
212 	  //capability |= vcg::tri::io::Mask::IOM_VERTFLAGS    ;
213 	  capability |= vcg::tri::io::Mask::IOM_VERTCOLOR    ;
214 	  capability |= vcg::tri::io::Mask::IOM_VERTQUALITY  ;
215 	  capability |= vcg::tri::io::Mask::IOM_VERTNORMAL   ;
216 	  //capability |= vcg::tri::io::Mask::IOM_VERTRADIUS   ;
217 	  capability |= vcg::tri::io::Mask::IOM_VERTTEXCOORD ;
218 	  //capability |= vcg::tri::io::Mask::IOM_FACEINDEX    ;
219 	  //capability |= vcg::tri::io::Mask::IOM_FACEFLAGS    ;
220 	  //capability |= vcg::tri::io::Mask::IOM_FACECOLOR    ;
221 	  //capability |= vcg::tri::io::Mask::IOM_FACEQUALITY  ;
222 	  // capability |= vcg::tri::io::Mask::IOM_FACENORMAL   ;
223 	  capability |= vcg::tri::io::Mask::IOM_WEDGCOLOR    ;
224 	  capability |= vcg::tri::io::Mask::IOM_WEDGTEXCOORD ;
225 	  capability |= vcg::tri::io::Mask::IOM_WEDGTEXMULTI ;
226     //capability |= vcg::tri::io::Mask::IOM_WEDGNORMAL   ;
227 	//	capability |= vcg::tri::io::Mask::IOM_CAMERA   ;
228 	  return capability;
229   }
230 
231 
232 }; // end class
233 
234 
235 
236 } // end namespace tri
237 } // end namespace io
238 } // end namespace vcg
239 //@}
240 #endif
241