Fix crash on linux
parent
499c3f439a
commit
8f5bbfd758
|
@ -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()) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue