This repository has been archived on 2020-10-03. You can view files and clone it, but cannot push or open issues or pull requests.
pgai_tp1/src/analysis.cpp

143 lines
3.4 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "analysis.h"
#include <cmath>
#include <iostream>
#include <fstream>
#define PI 3.14159265
bool check_faces_are_triangles(MyMesh &mesh) {
for (auto f_it = mesh.faces_begin(); f_it != mesh.faces_end(); ++f_it) {
size_t n_edges = 0;
for (auto fe_it = mesh.fe_iter(*f_it); fe_it.is_valid(); ++fe_it) {
n_edges++;
}
if (n_edges != 3) {
return false;
}
}
return true;
}
bool check_faces_arent_lonely(MyMesh &mesh) {
for (auto f_it = mesh.faces_begin(); f_it != mesh.faces_end(); ++f_it) {
auto ff_it = mesh.ff_iter(*f_it);
if (!ff_it.is_valid()) {
return false;
}
}
return true;
}
bool check_vertices_arent_lonely(MyMesh &mesh) {
for (auto v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it) {
auto ve_it = mesh.ve_iter(*v_it);
if (!ve_it.is_valid()) {
return false;
}
}
return true;
}
bool check_edges_arent_lonely(const char *path) {
using namespace std;
ifstream f(path);
string line;
while (getline(f, line)) {
istringstream iss(line);
char first;
iss >> first;
if (first == 'l') return false;
}
return true;
}
float face_area(MyMesh &mesh, const MyMesh::FaceHandle &face) {
MyMesh::Point p0, p1, p2;
auto fv_it = mesh.fv_iter(face);
p0 = mesh.point(*fv_it++);
p1 = mesh.point(*fv_it++);
p2 = mesh.point(*fv_it);
return ((p1 - p0) % (p2 - p0)).norm() / 2;
}
float total_area(MyMesh &mesh) {
if (!check_faces_are_triangles(mesh)) {
std::cerr << "Le calcul de laire ne peu se faire que sur un maillage triangulaire." << std::endl;
return -1;
}
float ret = 0;
for (const MyMesh::FaceHandle &face : mesh.faces()) {
ret += face_area(mesh, face);
}
return ret;
}
void stats_surface_area(MyMesh &mesh) {
if (!check_faces_are_triangles(mesh)) {
std::cerr << "Le calcul de laire ne peu se faire que sur un maillage triangulaire." << std::endl;
return;
}
for (const MyMesh::FaceHandle &face : mesh.faces()) {
std::cout << face_area(mesh, face) << " ";
}
std::cout << std::endl;
}
void stats_n_neighbors(MyMesh &mesh) {
for (const VertexHandle &vh : mesh.vertices()) {
unsigned count = 0;
for (auto vv_it = mesh.vv_iter(vh); vv_it.is_valid(); ++vv_it) {
count++;
}
std::cout << count << " ";
}
std::cout << std::endl;
}
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
static float f(int n, float h, float s, float v) {
float k = fmod(n + h / 60, 6);
return v - v * s * MAX(0, MIN(k, MIN(4 - k, 1)));
}
static OpenMesh::Vec3uc hsv_to_rgb(float h, float s, float v) {
return OpenMesh::Vec3uc {f(5, h, s, v) * 255, f(3, h, s, v) * 255, f(1, h, s, v) * 255};
}
void stats_normal_deviation(MyMesh &mesh) {
const float s = 1, v = 1, min_h = 50, max_h = 0;
mesh.update_normals();
for (const VertexHandle &vh : mesh.vertices()) {
MyMesh::Normal normal = mesh.normal(vh);
float max = 0;
for (auto vf_it = mesh.vf_iter(vh); vf_it.is_valid(); ++vf_it) {
float angle = acos(OpenMesh::dot(mesh.normal(*vf_it), normal)) * 180.0 / PI;
if (angle > max)
max = angle;
}
mesh.set_color(vh, (MyMesh::Color) hsv_to_rgb(fmod(max * 360 / (max_h - min_h) + max_h, 360), s, v));
std::cout << max << " ";
}
std::cout << std::endl;
}
void stats_dihedral_angles(MyMesh &mesh) {
mesh.update_normals();
for (size_t i = 0; i < mesh.n_halfedges(); i++) {
MyMesh::HalfedgeHandle heh = mesh.halfedge_handle(i);
std::cout << mesh.calc_dihedral_angle_fast(heh) * 180.0 / PI + 180 << " ";
}
std::cout << std::endl;
}