Skip to content

File ObjSerializer.cpp

File List > core > serializer > ObjSerializer.cpp

Go to the documentation of this file

#include "serializer/ObjSerializer.h"
#include <iostream>
#include <fstream>
#include <sstream>

#include "mesh/Face.h"
#include "mesh/Vertex.h"

namespace Argos{
    void ObjSerializer::serialize(const std::vector<Vector3D<double>> &vertices,
                                          const std::vector<Face> &faces,
                                          std::ostream& output) const {

        //écriture des sommets
        for(const auto& v : vertices){
            output << "v " << v.x << " " << v.y << " " << v.z << "\n";
        }

        //écriture des faces
        for(size_t i = 0; i < faces.size(); ++i){
            std::vector<int> face_vertices = faces.at(i).getIndices();
            output << "f";
            for (int j = 0; j < face_vertices.size(); ++j) {
                output << " " << (face_vertices[j] + 1); //+1 car OBJ commence à 1
            }
            output << "\n";
        }
    }

    void ObjSerializer::deserialize(std::vector<Vector3D<double>>& vertices, std::vector<Face>& faces, std::istream& input) const{

        std::string line;
        size_t currLineNumber = 0;

        while (std::getline(input, line)) {
            currLineNumber++;
            // trim de la ligne
            line.erase(0, line.find_first_not_of(" \t\r\n"));
            line.erase(line.find_last_not_of(" \t\r\n") + 1);

            if (line.empty() || line[0] == '#') continue; //pour ignorer commentaires et lignes vides

            std::istringstream iss(line);
            std::string type;
            iss >> type;

            if(type == "v"){
                double x, y, z;
                if (!(iss >> x >> y >> z)) {
                    std::cerr << "Attention : ligne 'v' mal formee : " << line << " a la ligne : " << currLineNumber << std::endl;
                    continue; // ignorer cette ligne
                }
                vertices.emplace_back(x, y, z);
            }
            else if(type == "f"){
                std::vector<int> verticesIdx;
                std::string vertexToken;
                while (iss >> vertexToken) {
                    // gérer les indices avec des '/' (ex: 1/2/3)
                    size_t slashPos = vertexToken.find('/');
                    if (slashPos != std::string::npos) {
                        vertexToken = vertexToken.substr(0, slashPos); // on ne garde que l'indice du sommet
                    }

                    try {
                        int vertexIndex = std::stoi(vertexToken);
                        vertexIndex--; // les indices OBJ commencent à 1
                        verticesIdx.push_back(vertexIndex);
                    } catch (const std::exception& e) {
                        std::cerr << "Attention : indice de la face invalide dans la ligne : " << line << " a la ligne : " << currLineNumber << std::endl;
                    }
                }

                faces.emplace_back(verticesIdx);
            }
        }
    }
}