kick
/Users/morten/Programmering/cpp/kick/src/kick/obj/obj_save.cpp
00001 //
00002 //  ObjSave.cpp
00003 //  KickObjLoader
00004 //
00005 //  Created by morten on 9/1/13.
00006 //  Copyright (c) 2013 morten. All rights reserved.
00007 //
00008 
00009 #include "obj_save.h"
00010 #include "obj_load.h"
00011 #include <fstream>
00012 #include <sstream>
00013 #include <cstring>
00014 
00015 using namespace std;
00016 using namespace glm;
00017 
00018 namespace kick {
00019     
00020     ostream& operator<<(ostream& cout,vec3 obj)
00021     {
00022         cout << obj[0]<<" "<<obj[1] << " "<<obj[2];
00023         return cout;
00024     }
00025 
00026     ostream& operator<<(ostream& cout,vec4 obj)
00027     {
00028         cout << obj[0]<<" "<<obj[1] << " "<<obj[2] << " "<<obj[3];
00029         return cout;
00030     }
00031     
00032     ostream& operator<<(ostream& cout,ObjVertex obj)
00033     {
00034         cout << " " << obj.vertexPositionIdx;
00035         if (obj.textureIdx>0){
00036             cout << "/"<<obj.textureIdx;
00037             if (obj.normalIdx>0){
00038                 cout << "/"<<obj.normalIdx;
00039             }
00040         } else if (obj.normalIdx>0){
00041             cout << "//"<<obj.normalIdx;
00042         }
00043         return cout;
00044     }
00045     
00046     
00047     string saveMaterialLib(ObjData & data, std::string path, std::string filename){
00048         size_t pos = filename.find_last_of('.');
00049         if (pos != string::npos){
00050             filename = filename.substr(0, pos);
00051         }
00052         filename += ".mtl";
00053         
00054         ofstream file;
00055         file.open ((path + filename).c_str());
00056         for (auto & material : data.materials){
00057             file << "newmtl "<<material.name<<endl;
00058             file << "Ns "<<material.specularCoefficient<<endl;
00059             file << "Ka "<<material.ambientColor<<endl;
00060             file << "Kd "<<material.diffuseColor<<endl;
00061             file << "Ks "<<material.specularColor<<endl;
00062             file << "d "<<material.transparent<<endl;
00063             for (auto & i : material.illuminationModes) {
00064                 file << "illum "<<static_cast<int>(i)<<endl;
00065             }
00066         }
00067         file.close();
00068         
00069         return filename;
00070     }
00071     
00072     void saveObjData(ObjData & data, std::string path, std::string filename){
00073         path = fixPathEnd(path);
00074         ofstream file;
00075         file.open ((path + filename).c_str());
00076         // save initial comment
00077         stringstream ss{data.initialComment};
00078         while (ss.good()){
00079             const int bufferSize = 256;
00080             char buffer[bufferSize];
00081             ss.getline(buffer, bufferSize);
00082             if (strlen(buffer)>0){
00083                 file << "# "<< buffer << endl;
00084             }
00085         }
00086         if (!data.materials.empty()){
00087             string name = saveMaterialLib(data, path, filename);
00088             file << "mtllib "<< name << endl;
00089         }
00090         for (auto & vertexPos: data.vertexPositions) {
00091             file << "v ";
00092             if (vertexPos[3] == 1){ // remove optional 4th value if possible
00093                 vec3 v{vertexPos[0],vertexPos[1],vertexPos[2]};
00094                  file << v << endl;
00095             } else {
00096                 file << vertexPos<<endl;
00097             }
00098         }
00099         for (auto & texCoord: data.textureCoords) {
00100             file << "vt ";
00101             if (texCoord[2] == 0){ // remove optional 3 coord if possible
00102                 file << texCoord[0] << " "<< texCoord[1]<<endl;
00103             } else {
00104                 file << texCoord << endl;
00105             }
00106         }
00107         for (auto & normal: data.normals) {
00108             file << "vn " << normal << endl;
00109         }
00110         int faceIndex = 1;
00111         auto materialIter = data.materialChanges.begin();
00112         auto materialIterEnd = data.materialChanges.end();
00113         auto smoothingGroupIter = data.smoothGroups.begin();
00114         auto smoothingGroupIterEnd = data.smoothGroups.end();
00115         for (auto & face : data.faces) {
00116             while (materialIter != materialIterEnd && materialIter->faceIndex==faceIndex){
00117                 file << "usemtl "<<materialIter->name<<endl;;
00118                 materialIter++;
00119             }
00120             while (smoothingGroupIter != smoothingGroupIterEnd && smoothingGroupIter->faceIndex==faceIndex){
00121                 int group = smoothingGroupIter->smoothGroupIdx;
00122                 file << "s ";
00123                 if (group == 0){
00124                     file << "off";
00125                 } else {
00126                     file << group;
00127                 }
00128                 file<<endl;;
00129                 smoothingGroupIter++;
00130             }
00131             file << "f";
00132             for (auto & vertexIndex : face) {
00133                 file << vertexIndex;
00134             }
00135             file << endl;
00136             faceIndex++;
00137         }
00138         
00139         file.close();
00140     }
00141 }
 All Classes Functions Variables