Cleaned up a bit the indentation and added support for saving line mesh in OBJ

This commit is contained in:
Paolo Cignoni 2013-07-26 09:35:44 +00:00
parent c5549f607a
commit 636f818107
1 changed files with 333 additions and 336 deletions
wrap/io_trimesh

View File

@ -37,369 +37,366 @@ namespace vcg {
namespace tri { namespace tri {
namespace io { namespace io {
template <class SaveMeshType> template <class SaveMeshType>
class ExporterOBJ class ExporterOBJ
{ {
public: public:
typedef typename SaveMeshType::FaceIterator FaceIterator; typedef typename SaveMeshType::FaceIterator FaceIterator;
typedef typename SaveMeshType::VertexIterator VertexIterator; typedef typename SaveMeshType::EdgeIterator EdgeIterator;
typedef typename SaveMeshType::VertexType VertexType; typedef typename SaveMeshType::VertexIterator VertexIterator;
typedef typename SaveMeshType::ScalarType ScalarType; typedef typename SaveMeshType::VertexType VertexType;
typedef typename SaveMeshType::CoordType CoordType; typedef typename SaveMeshType::ScalarType ScalarType;
/* typedef typename SaveMeshType::CoordType CoordType;
enum of all the types of error /*
*/ enum of all the types of error
enum SaveError */
{ enum SaveError
E_NOERROR, // 0 {
E_CANTOPENFILE, // 1 E_NOERROR, // 0
E_CANTCLOSEFILE, // 2 E_CANTOPENFILE, // 1
E_UNESPECTEDEOF, // 3 E_CANTCLOSEFILE, // 2
E_ABORTED, // 4 E_UNESPECTEDEOF, // 3
E_NOTDEFINITION, // 5 E_ABORTED, // 4
E_NOTVEXTEXVALID, // 6 E_NOTDEFINITION, // 5
E_NOTFACESVALID // 7 E_NOTVEXTEXVALID, // 6
}; E_NOTFACESVALID // 7
};
/* /*
this function takes an index and the relative error message gets back this function takes an index and the relative error message gets back
*/ */
static const char* ErrorMsg(int error) static const char* ErrorMsg(int error)
{ {
static const char* obj_error_msg[] = static const char* obj_error_msg[] =
{ {
"No errors", // 0 "No errors", // 0
"Can't open file", // 1 "Can't open file", // 1
"can't close file", // 2 "can't close file", // 2
"Premature End of file", // 3 "Premature End of file", // 3
"File saving aborted", // 4 "File saving aborted", // 4
"Function not defined", // 5 "Function not defined", // 5
"Vertices not valid", // 6 "Vertices not valid", // 6
"Faces not valid" // 7 "Faces not valid" // 7
}; };
if(error>7 || error<0) return "Unknown error"; if(error>7 || error<0) return "Unknown error";
else return obj_error_msg[error]; else return obj_error_msg[error];
}; };
/* /*
returns mask of capability one define with what are the saveable information of the format. returns mask of capability one define with what are the saveable information of the format.
*/ */
static int GetExportMaskCapability() static int GetExportMaskCapability()
{ {
int capability = 0; int capability = 0;
//vert //vert
capability |= vcg::tri::io::Mask::IOM_VERTNORMAL; capability |= vcg::tri::io::Mask::IOM_VERTNORMAL;
capability |= vcg::tri::io::Mask::IOM_VERTTEXCOORD; capability |= vcg::tri::io::Mask::IOM_VERTTEXCOORD;
capability |= vcg::tri::io::Mask::IOM_VERTCOLOR; capability |= vcg::tri::io::Mask::IOM_VERTCOLOR;
//face //face
capability |= vcg::tri::io::Mask::IOM_FACECOLOR; capability |= vcg::tri::io::Mask::IOM_FACECOLOR;
//wedg capability |= vcg::tri::io::Mask::IOM_EDGEINDEX;
capability |= vcg::tri::io::Mask::IOM_WEDGTEXCOORD; //wedg
capability |= vcg::tri::io::Mask::IOM_WEDGNORMAL; capability |= vcg::tri::io::Mask::IOM_WEDGTEXCOORD;
capability |= vcg::tri::io::Mask::IOM_WEDGNORMAL;
return capability; return capability;
} }
/* /*
function which saves in OBJ file format function which saves in OBJ file format
*/ */
static int Save(SaveMeshType &m, const char * filename, int mask, CallBackPos *cb=0) static int Save(SaveMeshType &m, const char * filename, int mask, CallBackPos *cb=0)
{ {
// texture coord and normal: cannot be saved BOTH per vertex and per wedge // texture coord and normal: cannot be saved BOTH per vertex and per wedge
if (mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD && if (mask & vcg::tri::io::Mask::IOM_WEDGTEXCOORD &&
mask & vcg::tri::io::Mask::IOM_VERTTEXCOORD ) { mask & vcg::tri::io::Mask::IOM_VERTTEXCOORD ) {
mask &= ~vcg::tri::io::Mask::IOM_VERTTEXCOORD; mask &= ~vcg::tri::io::Mask::IOM_VERTTEXCOORD;
} }
if (mask & vcg::tri::io::Mask::IOM_WEDGCOLOR && if (mask & vcg::tri::io::Mask::IOM_WEDGCOLOR &&
mask & vcg::tri::io::Mask::IOM_VERTCOLOR ) { mask & vcg::tri::io::Mask::IOM_VERTCOLOR ) {
mask &= ~vcg::tri::io::Mask::IOM_VERTCOLOR; mask &= ~vcg::tri::io::Mask::IOM_VERTCOLOR;
} }
if(m.vn == 0) return E_NOTVEXTEXVALID; if(m.vn == 0) return E_NOTVEXTEXVALID;
// Commented out this control. You should be allowed to save a point cloud. // Commented out this control. You should be allowed to save a point cloud.
// if(m.fn == 0) return E_NOTFACESVALID; // if(m.fn == 0) return E_NOTFACESVALID;
int current = 0; int current = 0;
int totalPrimitives = m.vn+m.fn; int totalPrimitives = m.vn+m.fn;
std::vector<Material> materialVec; std::vector<Material> materialVec;
std::string fn(filename); std::string fn(filename);
int LastSlash=fn.size()-1; int LastSlash=fn.size()-1;
while(LastSlash>=0 && fn[LastSlash]!='/') while(LastSlash>=0 && fn[LastSlash]!='/')
--LastSlash; --LastSlash;
FILE *fp; FILE *fp;
fp = fopen(filename,"w"); fp = fopen(filename,"w");
if(fp == NULL) return E_CANTOPENFILE; if(fp == NULL) return E_CANTOPENFILE;
fprintf(fp,"####\n#\n# OBJ File Generated by Meshlab\n#\n####\n"); fprintf(fp,"####\n#\n# OBJ File Generated by Meshlab\n#\n####\n");
fprintf(fp,"# Object %s\n#\n# Vertices: %d\n# Faces: %d\n#\n####\n",fn.substr(LastSlash+1).c_str(),m.vn,m.fn); fprintf(fp,"# Object %s\n#\n# Vertices: %d\n# Faces: %d\n#\n####\n",fn.substr(LastSlash+1).c_str(),m.vn,m.fn);
//library materialVec //library materialVec
if( (mask & vcg::tri::io::Mask::IOM_FACECOLOR) || (mask & Mask::IOM_WEDGTEXCOORD) ) if( (mask & vcg::tri::io::Mask::IOM_FACECOLOR) || (mask & Mask::IOM_WEDGTEXCOORD) )
fprintf(fp,"mtllib ./%s.mtl\n\n",fn.substr(LastSlash+1).c_str()); fprintf(fp,"mtllib ./%s.mtl\n\n",fn.substr(LastSlash+1).c_str());
//vertexs + normal //vertexs + normal
VertexIterator vi; VertexIterator vi;
std::map<CoordType,int> NormalVertex; std::map<CoordType,int> NormalVertex;
std::vector<int> VertexId(m.vert.size()); std::vector<int> VertexId(m.vert.size());
int numvert = 0; int numvert = 0;
int curNormalIndex = 1; int curNormalIndex = 1;
for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi) if( !(*vi).IsD() ) for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi) if( !(*vi).IsD() )
{ {
VertexId[vi-m.vert.begin()]=numvert; VertexId[vi-m.vert.begin()]=numvert;
//saves normal per vertex //saves normal per vertex
if (mask & Mask::IOM_WEDGNORMAL ) if (mask & Mask::IOM_WEDGNORMAL )
{ {
if(AddNewNormalVertex(NormalVertex,(*vi).N(),curNormalIndex)) if(AddNewNormalVertex(NormalVertex,(*vi).N(),curNormalIndex))
{ {
fprintf(fp,"vn %f %f %f\n",(*vi).N()[0],(*vi).N()[1],(*vi).N()[2]);
curNormalIndex++;
}
}
if (mask & Mask::IOM_VERTNORMAL ) {
fprintf(fp,"vn %f %f %f\n",(*vi).N()[0],(*vi).N()[1],(*vi).N()[2]); fprintf(fp,"vn %f %f %f\n",(*vi).N()[0],(*vi).N()[1],(*vi).N()[2]);
curNormalIndex++;
} }
if (mask & Mask::IOM_VERTTEXCOORD ) { }
fprintf(fp,"vt %f %f\n",(*vi).T().P()[0],(*vi).T().P()[1]); if (mask & Mask::IOM_VERTNORMAL ) {
fprintf(fp,"vn %f %f %f\n",(*vi).N()[0],(*vi).N()[1],(*vi).N()[2]);
}
if (mask & Mask::IOM_VERTTEXCOORD ) {
fprintf(fp,"vt %f %f\n",(*vi).T().P()[0],(*vi).T().P()[1]);
}
//if (mask & Mask::IOM_VERTCOLOR ) {
// fprintf(fp,"vc %f %f %f\n",(*vi).T().P()[0],(*vi).T().P()[1]);
//}
//saves vertex
fprintf(fp,"v %f %f %f",(*vi).P()[0],(*vi).P()[1],(*vi).P()[2]);
if(mask & Mask::IOM_VERTCOLOR)
fprintf(fp," %f %f %f",double((*vi).C()[0])/255.,double((*vi).C()[1])/255.,double((*vi).C()[2])/255.);
fprintf(fp,"\n");
if (cb !=NULL)
{
if(!(*cb)((100*++current)/totalPrimitives, "writing vertices "))
{
fclose(fp);
return E_ABORTED;
} }
//if (mask & Mask::IOM_VERTCOLOR ) { }
// fprintf(fp,"vc %f %f %f\n",(*vi).T().P()[0],(*vi).T().P()[1]); numvert++;
//} }
assert(numvert == m.vn);
//saves vertex fprintf(fp,"# %d vertices, %d vertices normals\n\n",m.vn,int(NormalVertex.size()));
fprintf(fp,"v %f %f %f",(*vi).P()[0],(*vi).P()[1],(*vi).P()[2]); //faces + texture coords
if(mask & Mask::IOM_VERTCOLOR) std::map<vcg::TexCoord2<ScalarType>,int> CoordIndexTexture;
fprintf(fp," %f %f %f",double((*vi).C()[0])/255.,double((*vi).C()[1])/255.,double((*vi).C()[2])/255.); unsigned int material_num = 0;
fprintf(fp,"\n"); int mem_index = 0; //var temporany
int curTexCoordIndex = 1;
for(FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi) if( !(*fi).IsD() )
{
if((mask & Mask::IOM_FACECOLOR) || (mask & Mask::IOM_WEDGTEXCOORD) )
{
int index = Materials<SaveMeshType>::CreateNewMaterial(m,materialVec,material_num,fi);
if (cb !=NULL) if(index == (int)materialVec.size())//inserts a new element material
{ {
if(!(*cb)((100*++current)/totalPrimitives, "writing vertices ")) material_num++;
{ fprintf(fp,"\nusemtl material_%d\n",materialVec[index-1].index);
fclose(fp); mem_index = index-1;
return E_ABORTED; }
} else
} {
numvert++; if(index != mem_index)//inserts old name elemente material
} {
assert(numvert == m.vn); fprintf(fp,"\nusemtl material_%d\n",materialVec[index].index);
mem_index=index;
}
}
}
fprintf(fp,"# %d vertices, %d vertices normals\n\n",m.vn,int(NormalVertex.size())); //saves texture coord x wedge
if(HasPerWedgeTexCoord(m) && (mask & Mask::IOM_WEDGTEXCOORD))
//faces + texture coords
FaceIterator fi;
std::map<vcg::TexCoord2<ScalarType>,int> CoordIndexTexture;
unsigned int material_num = 0;
int mem_index = 0; //var temporany
int curTexCoordIndex = 1;
for(fi=m.face.begin(); fi!=m.face.end(); ++fi) if( !(*fi).IsD() )
{
if((mask & Mask::IOM_FACECOLOR) || (mask & Mask::IOM_WEDGTEXCOORD) )
{
int index = Materials<SaveMeshType>::CreateNewMaterial(m,materialVec,material_num,fi);
if(index == (int)materialVec.size())//inserts a new element material
{
material_num++;
fprintf(fp,"\nusemtl material_%d\n",materialVec[index-1].index);
mem_index = index-1;
}
else
{
if(index != mem_index)//inserts old name elemente material
{
fprintf(fp,"\nusemtl material_%d\n",materialVec[index].index);
mem_index=index;
}
}
}
//saves texture coord x wedge
if(HasPerWedgeTexCoord(m) && (mask & Mask::IOM_WEDGTEXCOORD))
for(int k=0;k<(*fi).VN();k++) for(int k=0;k<(*fi).VN();k++)
{ {
{ if(AddNewTextureCoord(CoordIndexTexture,(*fi).WT(k),curTexCoordIndex))
if(AddNewTextureCoord(CoordIndexTexture,(*fi).WT(k),curTexCoordIndex)) {
{ fprintf(fp,"vt %f %f\n",(*fi).WT(k).u(),(*fi).WT(k).v());
fprintf(fp,"vt %f %f\n",(*fi).WT(k).u(),(*fi).WT(k).v()); curTexCoordIndex++; //ncreases the value number to be associated to the Texture
curTexCoordIndex++; //ncreases the value number to be associated to the Texture }
}
}
}
fprintf(fp,"f ");
for(int k=0;k<(*fi).VN();k++)
{
if(k!=0) fprintf(fp," ");
int vInd = -1;
// +1 because Obj file format begins from index = 1 but not from index = 0.
vInd = VertexId[GetIndexVertex(m, (*fi).V(k))] + 1;//index of vertex per face
int vt = -1;
if(mask & Mask::IOM_WEDGTEXCOORD)
vt = GetIndexVertexTexture(CoordIndexTexture,(*fi).WT(k));//index of vertex texture per face
if (mask & Mask::IOM_VERTTEXCOORD)
vt = vInd;
int vn = -1;
if(mask & Mask::IOM_WEDGNORMAL )
vn = GetIndexVertexNormal(m, NormalVertex, (*fi).V(k)->cN());//index of vertex normal per face.
if (mask & Mask::IOM_VERTNORMAL)
vn = vInd;
//writes elements on file obj
WriteFacesElement(fp,vInd,vt,vn);
}
fprintf(fp,"\n");
if (cb !=NULL) {
if(!(*cb)((100*++current)/totalPrimitives, "writing vertices "))
{ fclose(fp); return E_ABORTED;}
} }
}//for
fprintf(fp,"# %d faces, %d coords texture\n\n",m.fn,int(CoordIndexTexture.size()));
fprintf(fp,"# End of File\n"); fprintf(fp,"f ");
fclose(fp); for(int k=0;k<(*fi).VN();k++)
{
if(k!=0) fprintf(fp," ");
int vInd = -1;
// +1 because Obj file format begins from index = 1 but not from index = 0.
vInd = VertexId[tri::Index(m, (*fi).V(k))] + 1;//index of vertex per face
int r = 0; int vt = -1;
if((mask & Mask::IOM_WEDGTEXCOORD) || (mask & Mask::IOM_FACECOLOR) ) if(mask & Mask::IOM_WEDGTEXCOORD)
r = WriteMaterials(materialVec, filename,cb);//write material vt = GetIndexVertexTexture(CoordIndexTexture,(*fi).WT(k));//index of vertex texture per face
if (mask & Mask::IOM_VERTTEXCOORD)
vt = vInd;
if(r!= E_NOERROR) int vn = -1;
return r; if(mask & Mask::IOM_WEDGNORMAL )
return E_NOERROR; vn = GetIndexVertexNormal(m, NormalVertex, (*fi).V(k)->cN());//index of vertex normal per face.
} if (mask & Mask::IOM_VERTNORMAL)
vn = vInd;
/* //writes elements on file obj
returns index of the vertex WriteFacesElement(fp,vInd,vt,vn);
*/ }
inline static int GetIndexVertex(SaveMeshType &m, VertexType *p) fprintf(fp,"\n");
{
return p-&*(m.vert.begin());
}
/* if (cb !=NULL) {
returns index of the texture coord if(!(*cb)((100*++current)/totalPrimitives, "writing vertices "))
*/ { fclose(fp); return E_ABORTED;}
inline static int GetIndexVertexTexture(typename std::map<TexCoord2<ScalarType>,int> &mapTexToInt, const vcg::TexCoord2<ScalarType> &wt) }
{
typename std::map<vcg::TexCoord2<ScalarType>,int>::iterator iter= mapTexToInt.find(wt);
if(iter != mapTexToInt.end()) return (*iter).second;
else return -1;
// Old wrong version.
// int index = mapTexToInt[wt];
// if(index!=0){return index;}
}
/* }//for faces
returns index of the vertex normal
*/
inline static int GetIndexVertexNormal(SaveMeshType &/*m*/, std::map<CoordType,int> &mapNormToInt, const CoordType &norm )
{
typename std::map<CoordType,int>::iterator iter= mapNormToInt.find(norm);
if(iter != mapNormToInt.end()) return (*iter).second;
else return -1;
// Old wrong version.
// int index = mapNormToInt[m.vert[iv].N()];
// if(index!=0){return index;}
}
/* for(EdgeIterator ei=m.edge.begin(); ei!=m.edge.end(); ++ei) if( !(*ei).IsD() )
write elements on file {
fprintf(fp,"l %i %i\n",
VertexId[tri::Index(m, (*ei).V(0))] + 1,
VertexId[tri::Index(m, (*ei).V(1))] + 1);
}
f v/tc/vn v/tc/vn v/tc/vn ... fprintf(fp,"# %d faces, %d coords texture\n\n",m.fn,int(CoordIndexTexture.size()));
f v/tc v/tc v/tc ...
f v//vn v//vn v//vn ...
f v v v ...
*/ fprintf(fp,"# End of File\n");
inline static void WriteFacesElement(FILE *fp,int v,int vt, int vn) fclose(fp);
{
fprintf(fp,"%d",v);
if(vt!=-1)
{
fprintf(fp,"/%d",vt);
if(vn!=-1)
fprintf(fp,"/%d",vn);
}
else if(vn!=-1)
fprintf(fp,"//%d",vn);
}
/* int errCode = E_NOERROR;
adds a new index to the coordinate of Texture if it is the first time if((mask & Mask::IOM_WEDGTEXCOORD) || (mask & Mask::IOM_FACECOLOR) )
which is otherwise met not execute anything errCode = WriteMaterials(materialVec, filename,cb);//write material
*/
inline static bool AddNewTextureCoord(std::map<typename vcg::TexCoord2<ScalarType>,int> &m,
const typename vcg::TexCoord2<ScalarType> &wt,int value)
{
int index = m[wt];
if(index==0){m[wt]=value;return true;}
return false;
}
/* if(errCode!= E_NOERROR)
adds a new index to the normal per vertex if it is the first time return errCode;
which is otherwise met does not execute anything return E_NOERROR;
*/ }
inline static bool AddNewNormalVertex(typename std::map<CoordType,int> &m, CoordType &n ,int value)
{
int index = m[n];
if(index==0){m[n]=value;return true;}
return false;
}
/* /*
writes material into file returns index of the texture coord
*/ */
inline static int WriteMaterials(std::vector<Material> &materialVec, const char * filename, CallBackPos *cb=0) inline static int GetIndexVertexTexture(typename std::map<TexCoord2<ScalarType>,int> &mapTexToInt, const vcg::TexCoord2<ScalarType> &wt)
{ {
std::string fileName = std::string(filename); typename std::map<vcg::TexCoord2<ScalarType>,int>::iterator iter= mapTexToInt.find(wt);
fileName+=".mtl"; if(iter != mapTexToInt.end()) return (*iter).second;
else return -1;
// Old wrong version.
// int index = mapTexToInt[wt];
// if(index!=0){return index;}
}
if(materialVec.size() > 0) /*
{ returns index of the vertex normal
FILE *fp; */
fp = fopen(fileName.c_str(),"w"); inline static int GetIndexVertexNormal(SaveMeshType &/*m*/, std::map<CoordType,int> &mapNormToInt, const CoordType &norm )
if(fp==NULL)return E_ABORTED; {
typename std::map<CoordType,int>::iterator iter= mapNormToInt.find(norm);
if(iter != mapNormToInt.end()) return (*iter).second;
else return -1;
}
fprintf(fp,"#\n# Wavefront material file\n# Converted by Meshlab Group\n#\n\n"); /*
write elements on file
int current = 0; f v/tc/vn v/tc/vn v/tc/vn ...
f v/tc v/tc v/tc ...
f v//vn v//vn v//vn ...
f v v v ...
for(unsigned int i=0;i<materialVec.size();i++) */
{ inline static void WriteFacesElement(FILE *fp,int v,int vt, int vn)
if (cb !=NULL) {
(*cb)((100 * ++current)/materialVec.size(), "saving material file "); fprintf(fp,"%d",v);
else if(vt!=-1)
{ /* fclose(fp); return E_ABORTED; */ } {
fprintf(fp,"/%d",vt);
if(vn!=-1)
fprintf(fp,"/%d",vn);
}
else if(vn!=-1)
fprintf(fp,"//%d",vn);
}
fprintf(fp,"newmtl material_%d\n",materialVec[i].index); /*
fprintf(fp,"Ka %f %f %f\n",materialVec[i].Ka[0],materialVec[i].Ka[1],materialVec[i].Ka[2]); adds a new index to the coordinate of Texture if it is the first time
fprintf(fp,"Kd %f %f %f\n",materialVec[i].Kd[0],materialVec[i].Kd[1],materialVec[i].Kd[2]); which is otherwise met not execute anything
fprintf(fp,"Ks %f %f %f\n",materialVec[i].Ks[0],materialVec[i].Ks[1],materialVec[i].Ks[2]); */
fprintf(fp,"Tr %f\n",materialVec[i].Tr); inline static bool AddNewTextureCoord(std::map<typename vcg::TexCoord2<ScalarType>,int> &m,
fprintf(fp,"illum %d\n",materialVec[i].illum); const typename vcg::TexCoord2<ScalarType> &wt,int value)
fprintf(fp,"Ns %f\n",materialVec[i].Ns); {
int index = m[wt];
if(index==0){m[wt]=value;return true;}
return false;
}
if(materialVec[i].map_Kd.size()>0) /*
fprintf(fp,"map_Kd %s\n",materialVec[i].map_Kd.c_str()); adds a new index to the normal per vertex if it is the first time
fprintf(fp,"\n"); which is otherwise met does not execute anything
} */
fclose(fp); inline static bool AddNewNormalVertex(typename std::map<CoordType,int> &m, CoordType &n ,int value)
} {
return E_NOERROR; int index = m[n];
} if(index==0){m[n]=value;return true;}
return false;
}
}; // end class /*
writes material into file
*/
inline static int WriteMaterials(std::vector<Material> &materialVec, const char * filename, CallBackPos *cb=0)
{
std::string fileName = std::string(filename);
fileName+=".mtl";
if(materialVec.size() > 0)
{
FILE *fp;
fp = fopen(fileName.c_str(),"w");
if(fp==NULL)return E_ABORTED;
fprintf(fp,"#\n# Wavefront material file\n# Converted by Meshlab Group\n#\n\n");
int current = 0;
for(unsigned int i=0;i<materialVec.size();i++)
{
if (cb !=NULL)
(*cb)((100 * ++current)/materialVec.size(), "saving material file ");
else
{ /* fclose(fp); return E_ABORTED; */ }
fprintf(fp,"newmtl material_%d\n",materialVec[i].index);
fprintf(fp,"Ka %f %f %f\n",materialVec[i].Ka[0],materialVec[i].Ka[1],materialVec[i].Ka[2]);
fprintf(fp,"Kd %f %f %f\n",materialVec[i].Kd[0],materialVec[i].Kd[1],materialVec[i].Kd[2]);
fprintf(fp,"Ks %f %f %f\n",materialVec[i].Ks[0],materialVec[i].Ks[1],materialVec[i].Ks[2]);
fprintf(fp,"Tr %f\n",materialVec[i].Tr);
fprintf(fp,"illum %d\n",materialVec[i].illum);
fprintf(fp,"Ns %f\n",materialVec[i].Ns);
if(materialVec[i].map_Kd.size()>0)
fprintf(fp,"map_Kd %s\n",materialVec[i].map_Kd.c_str());
fprintf(fp,"\n");
}
fclose(fp);
}
return E_NOERROR;
}
}; // end class
} // end Namespace tri } // end Namespace tri
} // end Namespace io } // end Namespace io
} // end Namespace vcg } // end Namespace vcg