File meshobj_to_pointcloudobj.cpp
File List > apps > mesh_to_pointcloud > meshobj_to_pointcloudobj.cpp
Go to the documentation of this file
#include <fstream>
#include <iostream>
#include "argos/serializer/ObjSerializer.h"
#include "argos/mesh/Mesh.h"
using namespace Argos;
std::vector<Vector3D<double>> naiveSample(const Mesh& mesh) {
const std::vector<Vertex>& vertices = mesh.getVertices();
std::vector<Vector3D<double>> points;
points.reserve(vertices.size());
for (const Vertex& v : vertices) {
points.push_back(v.getPosition());
}
return points;
}
std::vector<Vector3D<double>> sampleMeshSurface(const Mesh& mesh, std::size_t pointCount) {
std::vector<Vector3D<double>> points;
points.reserve(pointCount);
const auto& faces = mesh.getFaces();
if (faces.empty())
return points;
for (std::size_t i = 0; i < pointCount; ++i) {
// 1. Choix al�atoire d�une face
const Face& face = faces[rand() % faces.size()];
//std::cout << "Sampling point " << i << " on face with " << face.getVertices().size() << " vertices." << std::endl; // DEBUG
const auto& vertexIndices = face.getIndices();
if (vertexIndices.size() < 3)
continue;
std::vector<Vertex> vertices;
for (auto& idx : vertexIndices) {
vertices.push_back(mesh.getVertices()[idx]);
}
// 2. Triangulation (en �ventail (fan triangulation))
std::size_t triIndex = 1 + rand() % (vertices.size() - 2);
const Vector3D<double>& A = vertices[0].getPosition();
const Vector3D<double>& B = vertices[triIndex].getPosition();
const Vector3D<double>& C = vertices[triIndex + 1].getPosition();
// 3. Coordonn�es barycentriques al�atoires
float u = static_cast<float>(rand()) / RAND_MAX;
float v = static_cast<float>(rand()) / RAND_MAX;
if (u + v > 1.0f) {
u = 1.0f - u;
v = 1.0f - v;
}
float alpha = 1.0f - u - v;
float beta = u;
float gamma = v;
//std::cout << "Barycentric coords: alpha=" << alpha << ", beta=" << beta << ", gamma=" << gamma << std::endl; // DEBUG
// 4. Construction du point
Vector3D<double> P = A * alpha + B * beta + C * gamma;
//std::cout << " -> Result : " << P << std::endl; // DEBUG
points.push_back(P);
}
return points;
}
std::vector<Face> convertFaces(const std::vector<int>& faces, const std::vector<int>& offsets) {
std::vector<Face> faces_convert;
std::vector<int> indices;
for (int j = 0; j < offsets.size(); j++) {
int fin;
if (j == offsets.size()-1) {
fin = faces.size();
}
else {
fin = offsets[j + 1];
}
for (int i = offsets[j]; i < fin; i++) {
indices.push_back(faces[i]);
}
faces_convert.emplace_back(indices);
indices.clear();
}
return faces_convert;
};
std::vector<Vertex> convertVertices(std::vector<Vector3D<double>> vectors3D) {
std::vector<Vertex> newVertices;
for (Vector3D<double> vec : vectors3D) {
newVertices.push_back(Vertex(vec));
}
return newVertices;
}
int main(int argc, char* argv[]) {
if (argc != 3) {
std::cout << "ERREUR : PAS ASSEZ D'ARGUMENTS (2 ou 3 attendus):" << std::endl;
std::cout << " -Arg1 : fichier OBJ en entree ou vont etre lu les sommets et faces" << std::endl;
std::cout << " -Arg2 : nombre de points genere par le surface sampling" << std::endl;
return -1;
}
ObjSerializer serializer = ObjSerializer();
std::vector<Vector3D<double>> vertices;
std::vector<int> faces;
std::vector<int> offsets;
try {
std::ifstream file(argv[0]);
serializer.deserialize(vertices, faces, offsets, file);
file.close();
}
catch (const std::runtime_error& e) {
return 0;
}
std::vector<Face> newFaces = convertFaces(faces, offsets);
std::vector<Vertex> newVertices = convertVertices(vertices);
Mesh mesh = Mesh(newVertices, newFaces);
std::vector<Vector3D<double>> pointCloudNaive = naiveSample(mesh);
std::vector<Vector3D<double>> pointCloudSurface = sampleMeshSurface(mesh, std::stoi(argv[2]));
try {
std::ofstream fileNaive("naive.obj");
std::ofstream fileSampling("naive.obj");
serializer.serialize(pointCloudNaive, std::vector<int>(), std::vector<int>(), fileNaive);
serializer.serialize(pointCloudSurface, std::vector<int>(), std::vector<int>(), fileSampling);
fileNaive.close();
fileSampling.close();
}
catch (const std::runtime_error& e) {
return 0;
}
return 0;
}