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   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(i%incr == 0)
79 	  	cb(++cbValue, "Exporting face topology");
80   }
81   fprintf(fout,"\n");
82   fprintf(fout,"]\n[\n");
83   qDebug("PointsPolygons %i",tt.elapsed());
84   cbValue = (++step)*cbStep; i=0;
85 
86   //second step: index of vertex for face
87   UpdateFlags<SaveMeshType>::VertexClearV(m);
88   for(FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi, ++i) {
89 	  if(i%incr == 0)
90 		  cb(++cbValue, "Exporting index of verteces");
91     for(int j=0; j<3; ++j) {
92       int indexOfVertex = (*fi).V(j) - &(m.vert[0]);
93 	    fprintf(fout,"%i ",indexOfVertex);
94 	    //if it's the first visit, set visited bit
95 	    if(!(*fi).V(j)->IsV()) {
96 		    (*fi).V(j)->SetV();
97 	    }
98 	  }
99 	  //fprintf(fout,"\n");
100 	  fprintf(fout," ");
101   }
102   fprintf(fout,"\n]\n");
103   qDebug("coords %i",tt.elapsed());
104   cbValue = (++step)*cbStep; i=0;
105 
106   //third step: vertex coordinates
107   fprintf(fout,"\"P\"\n[\n");
108   Matrix44f mat = Matrix44f::Identity();
109   mat = mat.SetScale(1.0,1.0,1.0);
110   incr = m.vn/cbStep;
111   for(VertexIterator vi=m.vert.begin(); vi!=m.vert.end(); ++vi, ++i) {
112     if(i%incr == 0) cb(++cbValue, "Exporting vertex coordinates");
113     if(vi->IsV()) {
114 	    Point3f p = mat * vi->P();
115 	    fprintf(fout,"%g %g %g ",p[0],p[1],p[2]);
116 	  }
117   }
118   fprintf(fout,"\n]\n");
119   qDebug("coords %i",tt.elapsed());
120 
121   incr = m.fn/cbStep; cbValue = (++step)*cbStep; i=0;
122   //fourth step: vertex normal
123   if(HasPerVertexNormal(m) && (savemask & Mask::IOM_VERTNORMAL)) {
124     fprintf(fout,"\"N\"\n[\n");
125     for(FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi, ++i) {
126 	    if(i%incr == 0) cb(++cbValue, "Exporting vertex normals");
127 	    //for each face, foreach vertex write normal
128 	    for(int j=0; j<3; ++j) {
129         Point3f n = mat * (*fi).V(j)->N(); //transform normal too
130         fprintf(fout,"%g %g %g ",n[0],n[1],n[2]);
131 	    }
132 	  }
133 	  fprintf(fout,"\n]\n");
134 	  qDebug("normal %i",tt.elapsed());
135   }
136   cbValue = (++step)*cbStep; i=0;
137 
138   //fifth step: vertex color (ignore face color?)
139   if(m.HasPerVertexColor() && (savemask & Mask::IOM_VERTCOLOR)) {
140     fprintf(fout,"\"Cs\"\n[\n");
141 	  for(FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi, ++i) {
142 	    if(i%incr == 0) cb(++cbValue, "Exporting vertex colors");
143 	    //for each face, foreach vertex write color
144 	    for(int j=0; j<3; ++j) {
145 	      Color4b &c=(*fi).V(j)->C();
146     		fprintf(fout,"%g %g %g ",float(c[0])/255,float(c[1])/255,float(c[2])/255);
147    	  }
148 	  }
149 	  fprintf(fout,"\n]\n");
150 	  qDebug("color %i",tt.elapsed());
151   }
152   cbValue = (++step)*cbStep; i=0;
153 
154   //sixth step: texture coordinates (for edge)
155   if((HasPerVertexTexCoord(m) && (savemask & Mask::IOM_VERTTEXCOORD)) ||
156 	  (HasPerWedgeTexCoord(m) && (savemask & Mask::IOM_WEDGTEXCOORD))) {
157   	fprintf(fout,"\"st\"\n[\n"); i=0;
158 	  for(FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi, ++i) {
159       if(i%incr == 0) cb(++cbValue, "Exporting vertex/edge texture coordinates");
160 	    //for each face, foreach vertex write uv coord
161 	    for(int j=0; j<3; ++j) {
162 	      fprintf(fout,"%g %g ",(*fi).WT(j).U() , 1.0 - (*fi).WT(j).V()); //v origin axis is up
163 	    }
164 	  }
165 	  fprintf(fout,"\n]\n");
166 	  qDebug("texcoords %i",tt.elapsed());
167   }
168   cbValue = (++step)*cbStep; i=0;
169 
170   //seventh step: vertex quality
171   if(HasPerVertexQuality(m) && (savemask & Mask::IOM_VERTQUALITY)) {
172 	  fprintf(fout,"\"Q\"\n[\n"); i=0;
173 	  for(FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi, ++i) {
174 	    if(i%incr == 0) cb(++cbValue, "Exporting vertex quality");
175 	    //for each face, foreach vertex write its quality
176 	    for(int j=0; j<3; ++j) {
177 	      fprintf(fout,"%g ",(*fi).V(j)->Q());
178   	  }
179   	}
180   	fprintf(fout,"\n]\n");
181   	qDebug("quality %i",tt.elapsed());
182   }
183   cb(100, "Exporting completed");
184   fclose(fout);
185 
186   return E_NOERROR;
187 }
188 
189 enum RibError {
190   E_NOERROR,				// 0
191 		// Errors of  open(..)
192 	E_CANTOPEN,				// 1
193 	E_MAXRIBERRORS
194 };
195 
ErrorMsg(int error)196 static const char *ErrorMsg(int error) {
197   static std::vector<std::string> rib_error_msg;
198   if(rib_error_msg.empty())
199   {
200     rib_error_msg.resize(E_MAXRIBERRORS);
201     rib_error_msg[E_NOERROR		]="No errors";
202 	  rib_error_msg[E_CANTOPEN  ]="Can't open file";
203   }
204 
205   if(error > E_MAXRIBERRORS || error < 0)
206     return "Unknown error";
207   else
208     return rib_error_msg[error].c_str();
209 };
210 
GetExportMaskCapability()211  static int GetExportMaskCapability() {
212 	  int capability = 0;
213 	  capability |= vcg::tri::io::Mask::IOM_VERTCOORD    ;
214 	  //capability |= vcg::tri::io::Mask::IOM_VERTFLAGS    ;
215 	  capability |= vcg::tri::io::Mask::IOM_VERTCOLOR    ;
216 	  capability |= vcg::tri::io::Mask::IOM_VERTQUALITY  ;
217 	  capability |= vcg::tri::io::Mask::IOM_VERTNORMAL   ;
218 	  //capability |= vcg::tri::io::Mask::IOM_VERTRADIUS   ;
219 	  capability |= vcg::tri::io::Mask::IOM_VERTTEXCOORD ;
220 	  //capability |= vcg::tri::io::Mask::IOM_FACEINDEX    ;
221 	  //capability |= vcg::tri::io::Mask::IOM_FACEFLAGS    ;
222 	  //capability |= vcg::tri::io::Mask::IOM_FACECOLOR    ;
223 	  //capability |= vcg::tri::io::Mask::IOM_FACEQUALITY  ;
224 	  // capability |= vcg::tri::io::Mask::IOM_FACENORMAL   ;
225 	  capability |= vcg::tri::io::Mask::IOM_WEDGCOLOR    ;
226 	  capability |= vcg::tri::io::Mask::IOM_WEDGTEXCOORD ;
227 	  capability |= vcg::tri::io::Mask::IOM_WEDGTEXMULTI ;
228     //capability |= vcg::tri::io::Mask::IOM_WEDGNORMAL   ;
229 	//	capability |= vcg::tri::io::Mask::IOM_CAMERA   ;
230 	  return capability;
231   }
232 
233 
234 }; // end class
235 
236 
237 
238 } // end namespace tri
239 } // end namespace io
240 } // end namespace vcg
241 //@}
242 #endif
243