<commit_before>// See LICENSE file for copyright and license details.

#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <stdexcept>
#include <GL/gl.h>
#include "core/dir.hpp"
#include "core/misc.hpp"
#include "ui/math.hpp"
#include "ui/vertexArray.hpp"
#include "ui/objModel.hpp"

ObjModel::ObjModel(const std::string& filename) {
  read(filename);
}

namespace {

V3f readVertexCoord(const char* buffer) {
  float x, y, z;
  int items = sscanf(buffer, "v %f %f %f", &x, &y, &z);
  if (items != 3) {
    throw std::logic_error("items != 3");
  }
  return V3f(x, y, z);
}

V3f readVertexNormal(const char* buffer) {
  float x, y, z;
  int items = sscanf(buffer, "vn %f %f %f", &x, &y, &z);
  if (items != 3) {
    throw std::logic_error("items != 3");
  }
  return V3f(x, y, z);
}

V2f readTextureCoords(const char* buffer) {
  float x, y;
  int items = sscanf(buffer, "vt %f %f", &x, &y);
  if (items != 2) {
    throw std::logic_error("items != 3");
  }
  y = 1.0f - y; // flip vertically
  return V2f(x, y);
}

ObjModel::ObjTriangle readFace(const char* buffer) {
  ObjModel::ObjTriangle t;
  int items = sscanf(buffer, "f %d/%d/%d %d/%d/%d %d/%d/%d",
      &t.vertex[0], &t.texture[0], &t.normal[0],
      &t.vertex[1], &t.texture[1], &t.normal[1],
      &t.vertex[2], &t.texture[2], &t.normal[2]);
  if (items != 9) {
    throw std::logic_error("items != 9");
  }
  return t;
}

} // namespace

// TODO "usemtl filename"
void ObjModel::read(const std::string& filename) {
  auto file = fopen(filename.c_str(), "r");
  if (!file) {
    throw std::logic_error(std::string("can't find file: ") + filename);
  }
  char buffer[100];
  while (fgets(buffer, 100, file)) {
    if (buffer[0] == 'v' && buffer[1] == ' ') {
      mVertices.push_back(readVertexCoord(buffer));
    } else if (buffer[0] == 'v' && buffer[1] == 'n') {
      mVertices.push_back(readVertexNormal(buffer));
    } else if (buffer[0] == 'v' && buffer[1] == 't') {
      mTextureCoords.push_back(readTextureCoords(buffer));
    } else if (buffer[0] == 'f' && buffer[1] == ' ') {
      mFaces.push_back(readFace(buffer));
    }
  }
  fclose(file);
}

void ObjModel::debugPrint() {
  for (auto v : mVertices) {
    printf("v %f %f %f\n", v.x(), v.y(), v.z());
  }
  for (auto v : mTextureCoords) {
    printf("t %f %f\n", v.x(), v.y());
  }
  for (auto f : mFaces) {
    printf("f %d/%d/%d %d/%d/%d %d/%d/%d\n",
        f.vertex[0], f.texture[0], f.normal[0],<commit_msg>ui/objModel.cpp: Added 'std::' to stdio's functions<commit_after>// See LICENSE file for copyright and license details.

#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <stdexcept>
#include <GL/gl.h>
#include "core/dir.hpp"
#include "core/misc.hpp"
#include "ui/math.hpp"
#include "ui/vertexArray.hpp"
#include "ui/objModel.hpp"

ObjModel::ObjModel(const std::string& filename) {
  read(filename);
}

namespace {

V3f readVertexCoord(const char* buffer) {
  float x, y, z;
  int items = std::sscanf(buffer, "v %f %f %f", &x, &y, &z);
  if (items != 3) {
    throw std::logic_error("items != 3");
  }
  return V3f(x, y, z);
}

V3f readVertexNormal(const char* buffer) {
  float x, y, z;
  int items = std::sscanf(buffer, "vn %f %f %f", &x, &y, &z);
  if (items != 3) {
    throw std::logic_error("items != 3");
  }
  return V3f(x, y, z);
}

V2f readTextureCoords(const char* buffer) {
  float x, y;
  int items = std::sscanf(buffer, "vt %f %f", &x, &y);
  if (items != 2) {
    throw std::logic_error("items != 3");
  }
  y = 1.0f - y; // flip vertically
  return V2f(x, y);
}

ObjModel::ObjTriangle readFace(const char* buffer) {
  ObjModel::ObjTriangle t;
  int items = std::sscanf(buffer, "f %d/%d/%d %d/%d/%d %d/%d/%d",
      &t.vertex[0], &t.texture[0], &t.normal[0],
      &t.vertex[1], &t.texture[1], &t.normal[1],
      &t.vertex[2], &t.texture[2], &t.normal[2]);
  if (items != 9) {
    throw std::logic_error("items != 9");
  }
  return t;
}

} // namespace

// TODO "usemtl filename"
void ObjModel::read(const std::string& filename) {
  auto file = std::fopen(filename.c_str(), "r");
  if (!file) {
    throw std::logic_error(std::string("can't find file: ") + filename);
  }
  char buffer[100];
  while (std::fgets(buffer, 100, file)) {
    if (buffer[0] == 'v' && buffer[1] == ' ') {
      mVertices.push_back(readVertexCoord(buffer));
    } else if (buffer[0] == 'v' && buffer[1] == 'n') {
      mVertices.push_back(readVertexNormal(buffer));
    } else if (buffer[0] == 'v' && buffer[1] == 't') {
      mTextureCoords.push_back(readTextureCoords(buffer));
    } else if (buffer[0] == 'f' && buffer[1] == ' ') {
      mFaces.push_back(readFace(buffer));
    }
  }
  std::fclose(file);
}

void ObjModel::debugPrint() {
  for (auto v : mVertices) {
    std::printf("v %f %f %f\n", v.x(), v.y(), v.z());
  }
  for (auto v : mTextureCoords) {
    std::printf("t %f %f\n", v.x(), v.y());
  }
  for (auto f : mFaces) {
    std::printf("f %d/%d/%d %d/%d/%d %d/%d/%d\n",
        f.vertex[0], f.texture[0], f.normal[0],
{'fraction_non_alphanumeric': 0.21794871794871795, 'fraction_numerical': 0.016826923076923076, 'mean_word_length': 3.498198198198198, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6765753', 'n_tokens_mistral': 2095, 'n_tokens_neox': 2040, 'n_words': 470}