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