00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef __VCGLIB_EXPORT_VMI
00025 #define __VCGLIB_EXPORT_VMI
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include <vcg/complex/complex.h>
00041
00042 namespace vcg {
00043 namespace tri {
00044 namespace io {
00045
00046 template <int N> struct PlaceHolderType{ char A[N];};
00047
00048
00049 template <class SaveMeshType>
00050 class ExporterVMI
00051 {
00052
00053
00054 static char * & Out_mem(){static char * out_mem; return out_mem;}
00055 static unsigned int & Out_mode(){static unsigned int out_mode = 0; return out_mode;}
00056
00057
00058 static unsigned int & pos(){static unsigned int p = 0; return p;}
00059 static int fwrite_sim(const void * , size_t size, size_t count){ pos() += size * count;return size * count; }
00060 static int fwrite_mem(const void *src , size_t size, size_t count ){ memcpy(&Out_mem()[pos()],src,size*count); pos() += size * count;return size * count; }
00061
00062
00063 static int WriteOut(const void * src, size_t size, size_t count){
00064 switch(Out_mode()){
00065 case 0: return fwrite_sim(src, size,count); break;
00066 case 1: return fwrite_mem(src, size,count); break;
00067 case 2: return fwrite(src, size,count, F() ); break;
00068 }
00069 assert(0);
00070 return 0;
00071 }
00072
00073
00074 static void WriteString( const char * in) { unsigned int l = strlen(in); WriteOut(&l,4,1 ); WriteOut(in,1,l );}
00075 static void WriteInt (const unsigned int i) { WriteOut(&i,1,4 );}
00076
00077 static void WriteFloat( const float v) { WriteOut(&v,1,sizeof(float) );}
00078
00079
00080 template <typename OpenMeshType,typename CONT>
00081 struct SaveVertexOcf{
00082 SaveVertexOcf( const CONT & , bool only_header){
00083
00084 if(only_header){
00085 WriteString( "NOT_HAS_VERTEX_QUALITY_OCF");
00086 WriteString( "NOT_HAS_VERTEX_COLOR_OCF");
00087 WriteString( "NOT_HAS_VERTEX_NORMAL_OCF");
00088 WriteString( "NOT_HAS_VERTEX_MARK_OCF");
00089 WriteString( "NOT_HAS_VERTEX_TEXCOORD_OCF");
00090 WriteString( "NOT_HAS_VERTEX_VFADJACENCY_OCF");
00091 WriteString( "NOT_HAS_VERTEX_CURVATURE_OCF");
00092 WriteString( "NOT_HAS_VERTEX_CURVATUREDIR_OCF");
00093 WriteString( "NOT_HAS_VERTEX_RADIUS_OCF");
00094 }
00095 }
00096 };
00097
00098
00099 template <typename MeshType>
00100 struct SaveVertexOcf<MeshType, vertex::vector_ocf<typename MeshType::VertexType> >{
00101 typedef typename MeshType::VertexType VertexType;
00102 SaveVertexOcf( const vertex::vector_ocf<VertexType> & vert, bool only_header){
00103
00104 if( VertexType::HasQualityOcf() && vert.IsQualityEnabled()){
00105 WriteString( "HAS_VERTEX_QUALITY_OCF");
00106 if(!only_header) WriteOut(&vert.QV[0],sizeof(typename VertexType::QualityType),vert.size() );
00107 }else WriteString( "NOT_HAS_VERTEX_QUALITY_OCF");
00108
00109 if( VertexType::HasColorOcf() && vert.IsColorEnabled()){
00110 WriteString( "HAS_VERTEX_COLOR_OCF");
00111 if(!only_header) WriteOut(&vert.CV[0],sizeof(typename VertexType::ColorType),vert.size() );
00112 }else WriteString( "NOT_HAS_VERTEX_COLOR_OCF");
00113
00114 if( VertexType::HasNormalOcf() && vert.IsNormalEnabled()){
00115 WriteString( "HAS_VERTEX_NORMAL_OCF");
00116 if(!only_header) WriteOut(&vert.NV[0],sizeof(typename VertexType::NormalType),vert.size() );
00117 }else WriteString( "NOT_HAS_VERTEX_NORMAL_OCF");
00118
00119 if( VertexType::HasMarkOcf() && vert.IsMarkEnabled()){
00120 WriteString( "HAS_VERTEX_MARK_OCF");
00121 if(!only_header) WriteOut(&vert.MV[0],sizeof(typename VertexType::MarkType),vert.size() );
00122 }else WriteString( "NOT_HAS_VERTEX_MARK_OCF");
00123
00124 if( VertexType::HasTexCoordOcf() && vert.IsTexCoordEnabled()){
00125 WriteString( "HAS_VERTEX_TEXCOORD_OCF");
00126 if(!only_header) WriteOut(&vert.TV[0],sizeof(typename VertexType::TexCoordType),vert.size() );
00127 }else WriteString( "NOT_HAS_VERTEX_TEXCOORD_OCF");
00128
00129 if( VertexType::HasVFAdjacencyOcf() && vert.IsVFAdjacencyEnabled()){
00130 WriteString( "HAS_VERTEX_VFADJACENCY_OCF");
00131 if(!only_header) WriteOut(&vert.AV[0],sizeof(typename vertex::vector_ocf<VertexType>::VFAdjType),vert.size() );
00132 }else WriteString( "NOT_HAS_VERTEX_VFADJACENCY_OCF");
00133
00134 if( VertexType::HasCurvatureOcf() && vert.IsCurvatureEnabled()){
00135 WriteString( "HAS_VERTEX_CURVATURE_OCF");
00136 if(!only_header) WriteOut(&vert.CuV[0],sizeof(typename VertexType::CurvatureType),vert.size() );
00137 }else WriteString( "NOT_HAS_VERTEX_CURVATURE_OCF");
00138
00139 if( VertexType::HasCurvatureDirOcf() && vert.IsCurvatureDirEnabled()){
00140 WriteString( "HAS_VERTEX_CURVATUREDIR_OCF");
00141 if(!only_header) WriteOut(&vert.CuDV[0],sizeof(typename VertexType::CurvatureDirType),vert.size() );
00142 }else WriteString( "NOT_HAS_VERTEX_CURVATUREDIR_OCF");
00143
00144 if( VertexType::HasRadiusOcf() && vert.IsRadiusEnabled()){
00145 WriteString( "HAS_VERTEX_RADIUS_OCF");
00146 if(!only_header) WriteOut(&vert.RadiusV[0],sizeof(typename VertexType::RadiusType),vert.size() );
00147 }else WriteString( "NOT_HAS_VERTEX_RADIUS_OCF");
00148
00149 }
00150 };
00151
00152
00153
00154 template <typename MeshType,typename CONT>
00155 struct SaveFaceOcf{
00156 SaveFaceOcf( const CONT & , bool only_header){
00157
00158 if(only_header){
00159 WriteString( "NOT_HAS_FACE_QUALITY_OCF");
00160 WriteString( "NOT_HAS_FACE_COLOR_OCF");
00161 WriteString( "NOT_HAS_FACE_NORMAL_OCF");
00162 WriteString( "NOT_HAS_FACE_MARK_OCF");
00163 WriteString( "NOT_HAS_FACE_WEDGETEXCOORD_OCF");
00164 WriteString( "NOT_HAS_FACE_FFADJACENCY_OCF");
00165 WriteString( "NOT_HAS_FACE_VFADJACENCY_OCF");
00166 WriteString( "NOT_HAS_FACE_WEDGECOLOR_OCF");
00167 WriteString( "NOT_HAS_FACE_WEDGENORMAL_OCF");
00168 }
00169 }
00170 };
00171
00172
00173 template <typename MeshType>
00174 struct SaveFaceOcf< MeshType, face::vector_ocf<typename MeshType::FaceType> >{
00175 typedef typename MeshType::FaceType FaceType;
00176 SaveFaceOcf( const face::vector_ocf<FaceType> & face, bool only_header){
00177
00178 if( FaceType::HasQualityOcf() && face.IsQualityEnabled()){
00179 WriteString( "HAS_FACE_QUALITY_OCF");
00180 if(!only_header) WriteOut(&face.QV[0],sizeof(typename FaceType::QualityType),face.size() );
00181 }else WriteString( "NOT_HAS_FACE_QUALITY_OCF");
00182
00183 if( FaceType::HasColorOcf() && face.IsColorEnabled()){
00184 WriteString( "HAS_FACE_COLOR_OCF");
00185 if(!only_header) WriteOut(&face.CV[0],sizeof(typename FaceType::ColorType),face.size() );
00186 }else WriteString( "NOT_HAS_FACE_COLOR_OCF");
00187
00188 if( FaceType::HasNormalOcf() && face.IsNormalEnabled()){
00189 WriteString( "HAS_FACE_NORMAL_OCF");
00190 if(!only_header) WriteOut(&face.NV[0],sizeof(typename FaceType::NormalType),face.size() );
00191 }else WriteString( "NOT_HAS_FACE_NORMAL_OCF");
00192
00193 if( FaceType::HasMarkOcf() && face.IsMarkEnabled()){
00194 WriteString( "HAS_FACE_MARK_OCF");
00195 if(!only_header) WriteOut(&face.MV[0],sizeof(typename FaceType::MarkType),face.size() );
00196 }else WriteString( "NOT_HAS_FACE_MARK_OCF");
00197
00198 if( FaceType::HasWedgeTexCoordOcf() && face.IsWedgeTexCoordEnabled()){
00199 WriteString( "HAS_FACE_WEDGETEXCOORD_OCF");
00200 if(!only_header) WriteOut(&face.WTV[0],sizeof(typename FaceType::WedgeTexCoordType),face.size() );
00201 }else WriteString( "NOT_HAS_FACE_WEDGETEXCOORD_OCF");
00202
00203 if( FaceType::HasFFAdjacencyOcf() && face.IsFFAdjacencyEnabled()){
00204 WriteString( "HAS_FACE_FFADJACENCY_OCF");
00205 if(!only_header) WriteOut(&face.AF[0],sizeof(typename face::vector_ocf<FaceType>::AdjTypePack),face.size() );
00206 }else WriteString( "NOT_HAS_FACE_FFADJACENCY_OCF");
00207
00208 if( FaceType::HasVFAdjacencyOcf() && face.IsVFAdjacencyEnabled()){
00209 WriteString( "HAS_FACE_VFADJACENCY_OCF");
00210 if(!only_header) WriteOut(&face.AV[0],sizeof(typename face::vector_ocf<FaceType>::AdjTypePack),face.size() );
00211 }else WriteString( "NOT_HAS_FACE_VFADJACENCY_OCF");
00212
00213 if( FaceType::HasWedgeColorOcf() && face.IsWedgeColorEnabled()){
00214 WriteString( "HAS_FACE_WEDGECOLOR_OCF");
00215 if(!only_header) WriteOut(&face.WCV[0],sizeof(typename face::vector_ocf<FaceType>::WedgeColorTypePack),face.size() );
00216 }else WriteString( "NOT_HAS_FACE_WEDGECOLOR_OCF");
00217
00218 if( FaceType::HasWedgeNormalOcf() && face.IsWedgeNormalEnabled()){
00219 WriteString( "HAS_FACE_WEDGENORMAL_OCF");
00220 if(!only_header) WriteOut(&face.WNV[0],sizeof(typename face::vector_ocf<FaceType>::WedgeNormalTypePack),face.size() );
00221 }else WriteString( "NOT_HAS_FACE_WEDGENORMAL_OCF");
00222 }
00223 };
00224
00225
00226
00227 static FILE *& F(){static FILE * f; return f;}
00228
00229 typedef typename SaveMeshType::FaceContainer FaceContainer;
00230 typedef typename SaveMeshType::FaceIterator FaceIterator;
00231 typedef typename SaveMeshType::VertContainer VertContainer;
00232 typedef typename SaveMeshType::VertexIterator VertexIterator;
00233 typedef typename SaveMeshType::VertexType VertexType;
00234 typedef typename SaveMeshType::FaceType FaceType;
00235 typedef SimpleTempDataBase STDBv;
00236 typedef SimpleTempDataBase STDBf;
00237
00238
00239
00240
00241
00242 public:
00243
00244 static int Save(const SaveMeshType &m,const char * filename){
00245 Out_mode() = 2;
00246 F() = fopen(filename,"wb");
00247 if(F()==NULL) return 1;
00248 int res = Serialize(m);
00249 fclose(F());
00250 return res;
00251 }
00252 static int DumpToMem(const SaveMeshType &m,char * ptr){
00253 Out_mode() = 1;
00254 pos() = 0;
00255 Out_mem() = ptr;
00256 return Serialize(m);
00257 }
00258 static int BufferSize(const SaveMeshType &m){
00259 Out_mode() = 0;
00260 pos() = 0 ;
00261 Serialize(m);
00262 return pos();
00263 }
00264
00265
00266 static int Serialize(const SaveMeshType &m){
00267 unsigned int i;
00268 unsigned int vertSize,faceSize;
00269 std::vector<std::string> nameF,nameV;
00270 SaveMeshType::FaceType::Name(nameF);
00271 SaveMeshType::VertexType::Name(nameV);
00272 vertSize = m.vert.size();
00273 faceSize = m.face.size();
00274
00275
00276 WriteString( "FACE_TYPE");
00277 WriteInt( nameF.size());
00278
00279 for(i=0; i < nameF.size(); ++i) WriteString( nameF[i].c_str());
00280 SaveFaceOcf<SaveMeshType,FaceContainer>( m.face,true);
00281 WriteString( "SIZE_VECTOR_FACES");
00282 WriteInt( faceSize );
00283
00284 WriteString( "VERTEX_TYPE");
00285 WriteInt( nameV.size());
00286
00287 for(i=0; i < nameV.size(); ++i) WriteString( nameV[i].c_str());
00288 SaveVertexOcf<SaveMeshType,VertContainer>( m.vert,true);
00289
00290 WriteString( "SIZE_VECTOR_VERTS");
00291 WriteInt( vertSize);
00292
00293 WriteString( "BOUNDING_BOX");
00294 float float_value;
00295 for(unsigned int i =0; i < 2; ++i){float_value = m.bbox.min[i]; WriteFloat( float_value);}
00296 for(unsigned int i =0; i < 2; ++i){float_value = m.bbox.max[i]; WriteFloat( float_value);}
00297
00298 WriteString( "end_header");
00299
00300
00301 if(vertSize!=0){
00302 void * offsetV = (void*) &m.vert[0];
00303
00304 WriteOut(&offsetV,sizeof(void *),1 );
00305 }
00306
00307 if(faceSize!=0){
00308 void * offsetF= (void*)&m.face[0];
00309
00310 WriteOut(&offsetF,sizeof( void *),1 );
00311 }
00312
00313
00314 WriteOut(&m.shot,sizeof(Shot<typename SaveMeshType::ScalarType>),1 );
00315 WriteOut(&m.vn,sizeof(int),1 );
00316 WriteOut(&m.fn,sizeof(int),1 );
00317 WriteOut(&m.imark,sizeof(int),1 );
00318 WriteOut(&m.bbox,sizeof(Box3<typename SaveMeshType::ScalarType>),1 );
00319 WriteOut(&m.C(),sizeof(Color4b),1 );
00320
00321 unsigned int written;
00322
00323
00324 if(vertSize!=0){
00325
00326 written = WriteOut((void*)&m.vert[0],sizeof(typename SaveMeshType::VertexType),m.vert.size() );
00327 SaveVertexOcf<SaveMeshType,VertContainer>( m.vert,false);
00328 }
00329
00330
00331 if(faceSize!=0){
00332
00333 written = WriteOut((void*)&m.face[0],sizeof(typename SaveMeshType::FaceType),faceSize );
00334 SaveFaceOcf<SaveMeshType,FaceContainer>( m.face,false);
00335
00336 }
00337
00338
00339
00340
00341 typename std::set< typename SaveMeshType::PointerToAttribute>::const_iterator ai;
00342
00343
00344
00345 {
00346 typename std::set< typename SaveMeshType::PointerToAttribute>::const_iterator ai;
00347 unsigned int n_named_attr = 0;
00348 for(ai = m.vert_attr.begin(); ai != m.vert_attr.end(); ++ai) n_named_attr+=!(*ai)._name.empty();
00349
00350 WriteString( "N_PER_VERTEX_ATTRIBUTES"); WriteInt ( n_named_attr);
00351 for(ai = m.vert_attr.begin(); ai != m.vert_attr.end(); ++ai)
00352 if(!(*ai)._name.empty())
00353 {
00354 STDBv * stdb = (STDBv *) (*ai)._handle;
00355
00356 WriteString( "PER_VERTEX_ATTR_NAME");
00357 WriteString( (*ai)._name.c_str() );
00358
00359 WriteString( "PER_VERTEX_ATTR_SIZE");
00360 WriteInt( stdb->SizeOf());
00361
00362 WriteOut(stdb->DataBegin(),m.vert.size(),stdb->SizeOf() );
00363 }
00364 }
00365
00366
00367 {
00368 typename std::set< typename SaveMeshType::PointerToAttribute>::const_iterator ai;
00369 unsigned int n_named_attr = 0;
00370 for(ai = m.face_attr.begin(); ai != m.face_attr.end(); ++ai) n_named_attr+=!(*ai)._name.empty();
00371
00372 WriteString( "N_PER_FACE_ATTRIBUTES");
00373 WriteInt ( n_named_attr);
00374
00375 for(ai = m.face_attr.begin(); ai != m.face_attr.end(); ++ai)
00376 if(!(*ai)._name.empty())
00377 {
00378 STDBf * stdb = (STDBf *) (*ai)._handle;
00379
00380 WriteString( "PER_FACE_ATTR_NAME");
00381 WriteString( (*ai)._name.c_str());
00382
00383 WriteString( "PER_FACE_ATTR_SIZE");
00384 WriteInt( stdb->SizeOf());
00385
00386 WriteOut(stdb->DataBegin(),m.face.size(),stdb->SizeOf() );
00387 }
00388 }
00389
00391 {
00392 typename std::set< typename SaveMeshType::PointerToAttribute>::const_iterator ai;
00393 unsigned int n_named_attr = 0;
00394 for(ai = m.mesh_attr.begin(); ai != m.mesh_attr.end(); ++ai) n_named_attr+=!(*ai)._name.empty();
00395 WriteString( "N_PER_MESH_ATTRIBUTES"); WriteInt( n_named_attr);
00396 for(ai = m.mesh_attr.begin(); ai != m.mesh_attr.end(); ++ai)
00397 if(!(*ai)._name.empty())
00398 {
00399 SimpleTempDataBase * handle = (SimpleTempDataBase *) (*ai)._handle ;
00400
00401 WriteString( "PER_MESH_ATTR_NAME");
00402 WriteString( (*ai)._name.c_str());
00403
00404 WriteString( "PER_MESH_ATTR_SIZE");
00405 WriteInt( handle->SizeOf());
00406
00407 WriteOut(handle->DataBegin(),1,handle->SizeOf() );
00408 }
00409 }
00410
00411
00412 return 0;
00413 }
00414 static const char *ErrorMsg(int error)
00415 {
00416 static std::vector<std::string> off_error_msg;
00417 if(off_error_msg.empty())
00418 {
00419 off_error_msg.resize(2 );
00420 off_error_msg[0]="No errors";
00421 off_error_msg[1]="Can't open file";
00422 }
00423
00424 if(error>1 || error<0) return "Unknown error";
00425 else return off_error_msg[error].c_str();
00426 }
00427 };
00428
00429 }
00430 }
00431 }
00432
00433 #endif