MySources/polymesh.hpp

209 lines
7.9 KiB
C++
Raw Normal View History

2020-11-27 11:47:21 +01:00
#ifndef POLYMESH_HPP
#define POLYMESH_HPP
2021-03-15 18:04:29 +01:00
#include "mesh.hpp"
2020-11-27 11:47:21 +01:00
#include "vcg/complex/complex.h"
#include <filesystem>
2021-04-08 20:03:23 +02:00
#include <polyscope/surface_mesh.h>
2020-11-27 11:47:21 +01:00
#include <wrap/io_trimesh/import.h>
class PFace;
class PVertex;
2021-04-08 20:03:23 +02:00
class PEdge;
2020-11-27 11:47:21 +01:00
struct PUsedTypes : public vcg::UsedTypes<vcg::Use<PVertex>::AsVertexType,
2021-04-08 20:03:23 +02:00
vcg::Use<PFace>::AsFaceType,
vcg::Use<PEdge>::AsEdgeType>
{};
class PVertex : public vcg::Vertex<PUsedTypes,
vcg::vertex::Coord3d,
vcg::vertex::Normal3d,
vcg::vertex::Mark,
vcg::vertex::Qualityf,
vcg::vertex::BitFlags,
vcg::vertex::VFAdj,
vcg::vertex::VEAdj>
{};
class PEdge : public vcg::Edge<PUsedTypes,
vcg::edge::VertexRef,
vcg::edge::BitFlags,
vcg::edge::EEAdj,
vcg::edge::VEAdj,
vcg::edge::EVAdj,
vcg::edge::EEAdj
// vcg::edge::EFAdj
>
{};
class PFace : public vcg::Face<PUsedTypes,
vcg::face::PolyInfo // this is necessary if you use component in
// vcg/simplex/face/component_polygon.h
// It says "this class is a polygon and the memory for its components
// (e.g. pointer to its vertices will be allocated dynamically")
,
vcg::face::VFAdj,
vcg::face::FEAdj,
vcg::face::PFVAdj,
// vcg::face::PVFAdj,
vcg::face::PFFAdj // Pointer to edge-adjacent face (just like FFAdj )
,
vcg::face::BitFlags // bit flags
,
vcg::face::Qualityf // quality
,
vcg::face::Normal3f // normal
>
{};
2020-11-27 11:47:21 +01:00
class VCGPolyMesh
2021-04-08 20:03:23 +02:00
: public vcg::tri::TriMesh<std::vector<PVertex>, std::vector<PFace>, std::vector<PEdge>>,
public Mesh
{
2020-11-27 11:47:21 +01:00
public:
2021-04-08 20:03:23 +02:00
// virtual bool load(const std::string &filename) override {
// int mask;
// vcg::tri::io::Importer<VCGPolyMesh>::LoadMask(filename.c_str(), mask);
// int error = vcg::tri::io::Importer<VCGPolyMesh>::Open(
// *this, filename.c_str(), mask);
// if (error != 0) {
// return false;
2020-11-27 11:47:21 +01:00
// }
2021-04-08 20:03:23 +02:00
// // vcg::tri::io::ImporterOBJ<VCGPolyMesh>::Open();
// // unsigned int mask = 0;
// // mask |= nanoply::NanoPlyWrapper<VCGPolyMesh>::IO_VERTCOORD;
// // mask |= nanoply::NanoPlyWrapper<VCGPolyMesh>::IO_VERTNORMAL;
// // mask |= nanoply::NanoPlyWrapper<VCGPolyMesh>::IO_VERTCOLOR;
// // mask |= nanoply::NanoPlyWrapper<VCGPolyMesh>::IO_EDGEINDEX;
// // mask |= nanoply::NanoPlyWrapper<VCGPolyMesh>::IO_FACEINDEX;
// // if (nanoply::NanoPlyWrapper<VCGPolyMesh>::LoadModel(
// // std::filesystem::absolute(filename).c_str(), *this, mask) !=
// // 0) {
// // std::cout << "Could not load tri mesh" << std::endl;
// // }
// vcg::tri::UpdateTopology<VCGPolyMesh>::FaceFace(*this);
// vcg::tri::UpdateTopology<VCGPolyMesh>::VertexEdge(*this);
// // vcg::tri::UpdateTopology<VCGPolyMesh>::VertexFace(*this);
// vcg::tri::UpdateNormal<VCGPolyMesh>::PerVertexNormalized(*this);
// return true;
// }
Eigen::MatrixX3d getVertices() const
{
Eigen::MatrixX3d vertices(VN(), 3);
for (size_t vi = 0; vi < VN(); vi++) {
VCGPolyMesh::CoordType vertexCoordinates = vert[vi].cP();
vertices.row(vi) = vertexCoordinates.ToEigenVector<Eigen::Vector3d>();
}
return vertices;
}
std::vector<std::vector<int>> getFaces() const
{
std::vector<std::vector<int>> faces(FN());
for (const VCGPolyMesh::FaceType &f : this->face) {
const int fi = vcg::tri::Index<VCGPolyMesh>(*this, f);
for (size_t vi = 0; vi < f.VN(); vi++) {
const size_t viGlobal = vcg::tri::Index<VCGPolyMesh>(*this, f.cV(vi));
faces[fi].push_back(viGlobal);
}
}
return faces;
2020-11-27 11:47:21 +01:00
}
2021-03-15 18:04:29 +01:00
#ifdef POLYSCOPE_DEFINED
2021-04-08 20:03:23 +02:00
std::shared_ptr<polyscope::SurfaceMesh> registerForDrawing(
const std::optional<std::array<double, 3>> &desiredColor = std::nullopt,
const bool &shouldEnable = true)
{
auto vertices = getVertices();
auto faces = getFaces();
initPolyscope();
2021-03-15 18:04:29 +01:00
2021-04-08 20:03:23 +02:00
std::shared_ptr<polyscope::SurfaceMesh> polyscopeHandle_mesh(
polyscope::registerSurfaceMesh(label, vertices, faces));
const double drawingRadius = 0.002;
polyscopeHandle_mesh->setEnabled(shouldEnable);
polyscopeHandle_mesh->setEdgeWidth(drawingRadius);
if (desiredColor.has_value()) {
const glm::vec3 desiredColor_glm(desiredColor.value()[0],
desiredColor.value()[1],
desiredColor.value()[2]);
polyscopeHandle_mesh->setSurfaceColor(desiredColor_glm);
}
return polyscopeHandle_mesh;
2021-03-15 18:04:29 +01:00
}
#endif
2021-04-08 20:03:23 +02:00
void moveToCenter()
{
CoordType centerOfMass(0, 0, 0);
for (int vi = 0; vi < VN(); vi++) {
centerOfMass += vert[vi].cP();
}
centerOfMass /= VN();
vcg::tri::UpdatePosition<VCGPolyMesh>::Translate(*this, -centerOfMass);
}
/*
* Returns the average distance from the center of each edge to the center of its face over the whole mesh
* */
double getAverageFaceRadius() const
{
double averageFaceRadius = 0;
for (int fi = 0; fi < FN(); fi++) {
const VCGPolyMesh::FaceType &f = face[fi];
CoordType centerOfFace(0, 0, 0);
for (int vi = 0; vi < f.VN(); vi++) {
centerOfFace = centerOfFace + f.cP(vi);
}
centerOfFace /= f.VN();
double faceRadius = 0;
// for (int face_ei = 0; face_ei < f.EN(); face_ei++) {
// std::cout << "fi:" << getIndex(f) << std::endl;
// auto vps = f.FVp(0);
// auto vpe = vps;
for (int i = 0; i < f.VN(); i++) {
faceRadius += vcg::Distance(centerOfFace, (f.cP0(i) + f.cP1(i)) / 2);
}
// }
const int faceEdges = f.VN(); //NOTE: When does this not hold?
faceRadius /= faceEdges;
averageFaceRadius += faceRadius;
}
averageFaceRadius /= FN();
return averageFaceRadius;
}
bool copy(VCGPolyMesh &copyFrom)
{
vcg::tri::Append<VCGPolyMesh, VCGPolyMesh>::MeshCopy(*this, copyFrom);
label = copyFrom.getLabel();
// eigenEdges = mesh.getEigenEdges();
// if (eigenEdges.rows() == 0) {
// getEdges(eigenEdges);
// }
// eigenVertices = mesh.getEigenVertices();
// if (eigenVertices.rows() == 0) {
// getVertices();
// }
vcg::tri::UpdateTopology<VCGPolyMesh>::VertexEdge(*this);
vcg::tri::UpdateTopology<VCGPolyMesh>::EdgeEdge(*this);
// vcg::tri::UpdateTopology<VCGPolyMesh>::VertexFace(*this);
return true;
}
VCGPolyMesh(VCGPolyMesh &copyFrom) { copy(copyFrom); }
VCGPolyMesh() {}
template<typename MeshElement>
size_t getIndex(const MeshElement &meshElement) const
{
return vcg::tri::Index<VCGPolyMesh>(*this, meshElement);
}
2020-11-27 11:47:21 +01:00
};
#endif // POLYMESH_HPP