1 /**************************************************************************** 2 * VCGLib o o * 3 * Visual and Computer Graphics Library o o * 4 * _ O _ * 5 * Copyright(C) 2004-2016 \/)\/ * 6 * Visual Computing Lab /\/| * 7 * ISTI - Italian National Research Council | * 8 * \ * 9 * All rights reserved. * 10 * * 11 * This program is free software; you can redistribute it and/or modify * 12 * it under the terms of the GNU General Public License as published by * 13 * the Free Software Foundation; either version 2 of the License, or * 14 * (at your option) any later version. * 15 * * 16 * This program is distributed in the hope that it will be useful, * 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 19 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * 20 * for more details. * 21 * * 22 ****************************************************************************/ 23 24 /** 25 @name Save in OFF format 26 */ 27 //@{ 28 29 #ifndef __VCGLIB_EXPORT_OFF 30 #define __VCGLIB_EXPORT_OFF 31 32 #include <stdio.h> 33 #include <wrap/io_trimesh/io_mask.h> 34 #include<wrap/io_trimesh/precision.h> 35 #include <vcg/complex/algorithms/clean.h> 36 #include <vcg/complex/algorithms/polygon_support.h> 37 38 39 namespace vcg { 40 namespace tri { 41 namespace io { 42 template <class SaveMeshType> 43 class ExporterOFF 44 { 45 46 public: 47 typedef typename SaveMeshType::VertexPointer VertexPointer; 48 typedef typename SaveMeshType::ScalarType ScalarType; 49 typedef typename SaveMeshType::VertexType VertexType; 50 typedef typename SaveMeshType::FaceType FaceType; 51 typedef typename SaveMeshType::FacePointer FacePointer; 52 typedef typename SaveMeshType::VertexIterator VertexIterator; 53 typedef typename SaveMeshType::FaceIterator FaceIterator; 54 55 static int Save(SaveMeshType &m, const char * filename, int mask=0 ) 56 { 57 vcg::face::Pos<FaceType> he; 58 vcg::face::Pos<FaceType> hei; 59 FILE * fpout = fopen(filename,"w"); 60 if(fpout==NULL) return 1; // 1 is the error code for cant'open, see the ErrorMsg function 61 62 63 if( tri::HasPerVertexColor(m) && (mask & io::Mask::IOM_VERTNORMAL)) 64 fprintf(fpout,"N"); 65 if( tri::HasPerVertexColor(m) && (mask & io::Mask::IOM_VERTCOLOR)) 66 fprintf(fpout,"C"); 67 if( tri::HasPerVertexTexCoord(m) && (mask & io::Mask::IOM_VERTTEXCOORD)) 68 fprintf(fpout,"ST"); 69 fprintf(fpout,"OFF\n"); 70 71 int polynumber; 72 if (mask &io::Mask::IOM_BITPOLYGONAL) 73 polynumber = tri::Clean<SaveMeshType>::CountBitLargePolygons(m); 74 else 75 polynumber = m.fn; 76 77 fprintf(fpout,"%d %d 0\n", m.vn, polynumber); // note that as edge number we simply write zero 78 79 //vertices 80 const int DGT = vcg::tri::io::Precision<ScalarType>::digits(); 81 for(auto vp=m.vert.begin();vp!=m.vert.end();++vp) 82 { 83 if( ! vp->IsD() ) 84 { // ***** ASCII ***** 85 86 fprintf(fpout,"%.*g %.*g %.*g " ,DGT,vp->P()[0],DGT,vp->P()[1],DGT,vp->P()[2]); 87 if( tri::HasPerVertexColor(m) && (mask & io::Mask::IOM_VERTCOLOR) ) 88 fprintf(fpout,"%d %d %d %d ",vp->C()[0],vp->C()[1],vp->C()[2],vp->C()[3] ); 89 90 if( tri::HasPerVertexNormal(m) && (mask & io::Mask::IOM_VERTNORMAL) ) 91 fprintf(fpout,"%g %g %g ", double(vp->N()[0]),double(vp->N()[1]),double(vp->N()[2])); 92 93 if( tri::HasPerVertexTexCoord(m) && (mask & io::Mask::IOM_VERTTEXCOORD) ) 94 fprintf(fpout,"%g %g ",vp->T().u(),vp->T().v()); 95 96 fprintf(fpout,"\n"); 97 } 98 } 99 100 101 if (mask &io::Mask::IOM_BITPOLYGONAL) { 102 tri::RequireFFAdjacency(m); 103 std::vector<VertexPointer> polygon; 104 tri::UpdateFlags<SaveMeshType>::FaceClearV(m); 105 for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) if (!fi->IsD()) if (!fi->IsV()) { 106 vcg::tri::PolygonSupport<SaveMeshType,SaveMeshType>::ExtractPolygon(&*fi,polygon); 107 if(!polygon.empty()) 108 { 109 fprintf(fpout,"%d ", int(polygon.size()) ); 110 for (size_t i=0; i<polygon.size(); i++) fprintf(fpout,"%d ", polygon[i]->Flags() ); 111 fprintf(fpout,"\n"); 112 } 113 } 114 } 115 else { 116 for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) 117 { 118 if( ! fi->IsD() ) 119 { 120 fprintf(fpout,"%i ",fi->VN()); 121 for(int i=0;i<fi->VN();++i) 122 fprintf(fpout,"%lu ",tri::Index(m,fi->V(i))); 123 if( tri::HasPerFaceColor(m) && (mask & io::Mask::IOM_FACECOLOR) ) 124 fprintf(fpout,"%i %i %i", fi->C()[0],fi->C()[1],fi->C()[2] ); 125 fprintf(fpout,"\n"); 126 } 127 } 128 } 129 130 int result = 0; 131 if (ferror(fpout)) result = 2; 132 fclose(fpout); 133 return result; 134 } 135 ErrorMsg(int error)136 static const char *ErrorMsg(int error) 137 { 138 static std::vector<std::string> off_error_msg; 139 if (off_error_msg.empty()) 140 { 141 off_error_msg.resize(3); 142 off_error_msg[0] = "No errors"; 143 off_error_msg[1] = "Can't open file"; 144 off_error_msg[2] = "Output Stream error"; 145 } 146 147 if (error>2 || error<0) return "Unknown error"; 148 else return off_error_msg[error].c_str(); 149 } 150 /* 151 returns mask of capability one define with what are the saveable information of the format. 152 */ GetExportMaskCapability()153 static int GetExportMaskCapability() 154 { 155 int capability = 0; 156 capability |= vcg::tri::io::Mask::IOM_VERTCOORD; 157 capability |= vcg::tri::io::Mask::IOM_VERTCOLOR; 158 capability |= vcg::tri::io::Mask::IOM_VERTTEXCOORD; 159 capability |= vcg::tri::io::Mask::IOM_FACEINDEX; 160 capability |= vcg::tri::io::Mask::IOM_FACECOLOR; 161 capability |= vcg::tri::io::Mask::IOM_BITPOLYGONAL; 162 return capability; 163 } 164 165 }; // end class 166 } // end namespace tri 167 } // end namespace io 168 } // end namespace vcg 169 //@} 170 #endif 171