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