mod_geo-tp/src/mesh_processor.cpp

134 lines
3.2 KiB
C++

#include "quad_patch_tesselator.h"
#include "mesh_processor.h"
#include "util.h"
#include "hole_filling.h"
#include "smoothing.h"
#include "curvature.h"
#include <QGenericMatrix>
#include <unordered_set>
MeshProcessor::MeshProcessor(const QString &path, MeshViewer &mesh_viewer,
double implicit_hole_filling_scale,
double implicit_hole_filling_discr)
:mesh_viewer(mesh_viewer),
implicit_hole_filling_scale(implicit_hole_filling_scale),
implicit_hole_filling_discr(implicit_hole_filling_discr) {
OpenMesh::IO::Options options;
options.set(OpenMesh::IO::Options::VertexColor);
if (!OpenMesh::IO::read_mesh(mesh, path.toUtf8().constData(), options)) {
qWarning() << "Failed to read" << path;
return;
}
for (VertexHandle vh : mesh.vertices()) {
mesh.set_color(vh, MyMesh::Color(.5, .5, .5));
}
courbure = new Courbures(mesh);
try {
courbure->compute_KH();
courbure->set_K_colors();
} catch (std::runtime_error &e) {
qWarning() << "Curvature computation failed";
}
connect(&mesh_viewer, &MeshViewer::clicked, this, &MeshProcessor::click);
updateView();
}
MeshProcessor::~MeshProcessor() {
if (mesh_viewer.isInitialized()) {
mesh_viewer.removeMesh(mesh);
}
if (courbure) delete courbure;
}
void MeshProcessor::updateView() const {
if (mesh_viewer.isInitialized()) {
mesh_viewer.removeMesh(mesh);
mesh_viewer.addMesh(mesh);
mesh_viewer.updateForReal();
} else {
connect(&mesh_viewer, &MeshViewer::initialized, [&]() {
mesh_viewer.addMesh(mesh);
mesh_viewer.updateForReal();
});
}
}
void MeshProcessor::fillHolesDumb() {
::fillHolesDumb(mesh);
updateView();
}
void MeshProcessor::fillHolesImplicit() {
for (MyMesh &filling : fillings) {
mesh_viewer.removeMesh(filling);
}
std::vector<MyMesh> new_fillings =
::fillHolesImplicit(mesh,
implicit_hole_filling_scale,
implicit_hole_filling_discr);
for (MyMesh &filling : new_fillings) {
fillings.push_back(filling);
mesh_viewer.addMesh(fillings[fillings.size() - 1]);
}
updateView();
}
void MeshProcessor::setImplicitHoleFillingScale(float scale) {
implicit_hole_filling_scale = scale;
if (fillings.size() > 0) {
fillHolesImplicit();
}
}
void MeshProcessor::setImplicitHoleFillingDiscr(float discr) {
implicit_hole_filling_discr = discr;
if (fillings.size() > 0) {
fillHolesImplicit();
}
}
void MeshProcessor::smoothCotangent(double factor) {
::smooth(mesh, SmoothingMethod::COTANGENT, factor);
updateView();
}
void MeshProcessor::smoothUniform() {
::smooth(mesh, SmoothingMethod::UNIFORM);
updateView();
}
void MeshProcessor::setPatchView(bool on) {
view_patches = on;
}
void MeshProcessor::click(QVector3D position) {
if (!view_patches) return;
Eigen::Vector3d pos {position.x(), position.y(), position.z()};
MyMesh::VertexIter it = mesh.vertices_begin();
VertexHandle min_vert = *it;
double min_dist = (mesh.point(*it) - pos).squaredNorm();
for (; it != mesh.vertices_end(); ++it) {
double dist = (mesh.point(*it) - pos).squaredNorm();
if (dist < min_dist) {
min_dist = dist;
min_vert = *it;
}
}
QuadPatch q = mesh.property(courbure->vprop_quad, min_vert);
patch = tesselate_quad_patch(q, mesh, min_vert);
mesh_viewer.removeMesh(patch);
mesh_viewer.addMesh(patch);
mesh_viewer.updateForReal();
}