Fix crash on linux

master
Jeremy Hu 2019-03-08 20:25:24 +09:30
parent 499c3f439a
commit 8f5bbfd758
4 changed files with 62 additions and 18 deletions

View File

@ -4,6 +4,8 @@
#include <CGAL/Surface_mesh.h>
#include <QVector3D>
#include <vector>
#include <cmath>
#include <nodemesh/misc.h>
typedef CGAL::Exact_predicates_exact_constructions_kernel ExactKernel;
typedef CGAL::Surface_mesh<ExactKernel::Point_3> ExactMesh;
@ -15,6 +17,16 @@ typename CGAL::Surface_mesh<typename Kernel::Point_3> *buildCgalMesh(const std::
std::map<size_t, typename CGAL::Surface_mesh<typename Kernel::Point_3>::Vertex_index> vertexIndices;
for (const auto &face: indices) {
std::vector<typename CGAL::Surface_mesh<typename Kernel::Point_3>::Vertex_index> faceVertexIndices;
bool faceValid = true;
for (const auto &index: face) {
const auto &pos = positions[index];
if (!nodemesh::validatePosition(pos)) {
faceValid = false;
break;
}
}
if (!faceValid)
continue;
for (const auto &index: face) {
auto findIndex = vertexIndices.find(index);
if (findIndex != vertexIndices.end()) {

View File

@ -18,34 +18,27 @@ Combiner::Mesh::Mesh(const std::vector<QVector3D> &vertices, const std::vector<s
{
ExactMesh *cgalMesh = nullptr;
if (!faces.empty()) {
cgalMesh = buildCgalMesh<ExactKernel>(vertices, faces);
if (!CGAL::is_valid_polygon_mesh(*cgalMesh)) {
qDebug() << "Mesh is not valid polygon";
delete cgalMesh;
cgalMesh = nullptr;
} else {
if (CGAL::Polygon_mesh_processing::triangulate_faces(*cgalMesh)) {
std::vector<QVector3D> triangleVertices = vertices;
std::vector<std::vector<size_t>> triangles;
if (nodemesh::triangulate(triangleVertices, faces, triangles)) {
cgalMesh = buildCgalMesh<ExactKernel>(triangleVertices, triangles);
if (!CGAL::is_valid_polygon_mesh(*cgalMesh)) {
qDebug() << "Mesh is not valid polygon";
delete cgalMesh;
cgalMesh = nullptr;
} else {
if (CGAL::Polygon_mesh_processing::does_self_intersect(*cgalMesh)) {
//nodemesh::exportMeshAsObj(vertices, triangles, "/Users/jeremy/Desktop/test.obj");
m_isSelfIntersected = true;
if (removeSelfIntersects) {
if (!CGAL::Polygon_mesh_processing::remove_self_intersections(*cgalMesh)) {
//qDebug() << "Mesh does self intersect and cann't remove intersections";
delete cgalMesh;
cgalMesh = nullptr;
} else {
//qDebug() << "Mesh does self intersect but intersections got removed";
}
} else {
delete cgalMesh;
cgalMesh = nullptr;
//qDebug() << "Mesh does self intersect";
}
}
} else {
qDebug() << "Mesh triangulate failed";
delete cgalMesh;
cgalMesh = nullptr;
}
}
}

View File

@ -5,6 +5,12 @@
#include <QDebug>
#include <unordered_set>
#include <unordered_map>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Polygon_mesh_processing/triangulate_faces.h>
#include <nodemesh/cgalmesh.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel InexactKernel;
typedef CGAL::Surface_mesh<InexactKernel::Point_3> InexactMesh;
#ifndef M_PI
#define M_PI 3.14159265358979323846
@ -72,8 +78,38 @@ bool nodemesh::pointInTriangle(const QVector3D &a, const QVector3D &b, const QVe
return r + t <= 1.0;
}
void nodemesh::triangulate(const std::vector<QVector3D> &vertices, const std::vector<std::vector<size_t>> &faces, std::vector<std::vector<size_t>> &triangles)
bool nodemesh::validatePosition(const QVector3D &position)
{
if (std::isnan(position.x()))
return false;
if (std::isnan(position.y()))
return false;
if (std::isnan(position.z()))
return false;
if (std::isinf(position.x()))
return false;
if (std::isinf(position.y()))
return false;
if (std::isinf(position.z()))
return false;
return true;
}
bool nodemesh::triangulate(std::vector<QVector3D> &vertices, const std::vector<std::vector<size_t>> &faces, std::vector<std::vector<size_t>> &triangles)
{
auto cgalMesh = buildCgalMesh<InexactKernel>(vertices, faces);
bool isSucceed = CGAL::Polygon_mesh_processing::triangulate_faces(*cgalMesh);
if (isSucceed) {
vertices.clear();
fetchFromCgalMesh<InexactKernel>(cgalMesh, vertices, triangles);
delete cgalMesh;
return true;
}
delete cgalMesh;
// fallback to our own imeplementation
isSucceed = true;
std::vector<std::vector<size_t>> rings;
for (const auto &face: faces) {
if (face.size() > 3) {
@ -128,8 +164,10 @@ void nodemesh::triangulate(const std::vector<QVector3D> &vertices, const std::ve
triangles.push_back(newFace);
} else {
qDebug() << "Triangulate failed, ring size:" << fillRing.size();
isSucceed = false;
}
}
return isSucceed;
}
void nodemesh::exportMeshAsObj(const std::vector<QVector3D> &vertices, const std::vector<std::vector<size_t>> &faces, const QString &filename, const std::set<size_t> *excludeFacesOfVertices)

View File

@ -16,7 +16,7 @@ float degreeBetween(const QVector3D &v1, const QVector3D &v2);
float degreeBetweenIn360(const QVector3D &a, const QVector3D &b, const QVector3D &direct);
bool pointInTriangle(const QVector3D &a, const QVector3D &b, const QVector3D &c, const QVector3D &p);
QVector3D polygonNormal(const std::vector<QVector3D> &vertices, const std::vector<size_t> &polygon);
void triangulate(const std::vector<QVector3D> &vertices, const std::vector<std::vector<size_t>> &faces, std::vector<std::vector<size_t>> &triangles);
bool triangulate(std::vector<QVector3D> &vertices, const std::vector<std::vector<size_t>> &faces, std::vector<std::vector<size_t>> &triangles);
void exportMeshAsObj(const std::vector<QVector3D> &vertices, const std::vector<std::vector<size_t>> &faces, const QString &filename, const std::set<size_t> *excludeFacesOfVertices=nullptr);
void exportMeshAsObjWithNormals(const std::vector<QVector3D> &vertices, const std::vector<std::vector<size_t>> &faces, const QString &filename,
const std::vector<QVector3D> &triangleVertexNormals);
@ -34,6 +34,7 @@ bool isManifold(const std::vector<std::vector<size_t>> &faces);
void trim(std::vector<QVector3D> *vertices, bool normalize=false);
void subdivideFace2D(std::vector<QVector2D> *face);
void chamferFace2D(std::vector<QVector2D> *face);
bool validatePosition(const QVector3D &position);
}