Fix crash on linux
parent
499c3f439a
commit
8f5bbfd758
|
@ -4,6 +4,8 @@
|
||||||
#include <CGAL/Surface_mesh.h>
|
#include <CGAL/Surface_mesh.h>
|
||||||
#include <QVector3D>
|
#include <QVector3D>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <cmath>
|
||||||
|
#include <nodemesh/misc.h>
|
||||||
|
|
||||||
typedef CGAL::Exact_predicates_exact_constructions_kernel ExactKernel;
|
typedef CGAL::Exact_predicates_exact_constructions_kernel ExactKernel;
|
||||||
typedef CGAL::Surface_mesh<ExactKernel::Point_3> ExactMesh;
|
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;
|
std::map<size_t, typename CGAL::Surface_mesh<typename Kernel::Point_3>::Vertex_index> vertexIndices;
|
||||||
for (const auto &face: indices) {
|
for (const auto &face: indices) {
|
||||||
std::vector<typename CGAL::Surface_mesh<typename Kernel::Point_3>::Vertex_index> faceVertexIndices;
|
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) {
|
for (const auto &index: face) {
|
||||||
auto findIndex = vertexIndices.find(index);
|
auto findIndex = vertexIndices.find(index);
|
||||||
if (findIndex != vertexIndices.end()) {
|
if (findIndex != vertexIndices.end()) {
|
||||||
|
|
|
@ -18,34 +18,27 @@ Combiner::Mesh::Mesh(const std::vector<QVector3D> &vertices, const std::vector<s
|
||||||
{
|
{
|
||||||
ExactMesh *cgalMesh = nullptr;
|
ExactMesh *cgalMesh = nullptr;
|
||||||
if (!faces.empty()) {
|
if (!faces.empty()) {
|
||||||
cgalMesh = buildCgalMesh<ExactKernel>(vertices, faces);
|
std::vector<QVector3D> triangleVertices = vertices;
|
||||||
if (!CGAL::is_valid_polygon_mesh(*cgalMesh)) {
|
std::vector<std::vector<size_t>> triangles;
|
||||||
qDebug() << "Mesh is not valid polygon";
|
if (nodemesh::triangulate(triangleVertices, faces, triangles)) {
|
||||||
delete cgalMesh;
|
cgalMesh = buildCgalMesh<ExactKernel>(triangleVertices, triangles);
|
||||||
cgalMesh = nullptr;
|
if (!CGAL::is_valid_polygon_mesh(*cgalMesh)) {
|
||||||
} else {
|
qDebug() << "Mesh is not valid polygon";
|
||||||
if (CGAL::Polygon_mesh_processing::triangulate_faces(*cgalMesh)) {
|
delete cgalMesh;
|
||||||
|
cgalMesh = nullptr;
|
||||||
|
} else {
|
||||||
if (CGAL::Polygon_mesh_processing::does_self_intersect(*cgalMesh)) {
|
if (CGAL::Polygon_mesh_processing::does_self_intersect(*cgalMesh)) {
|
||||||
//nodemesh::exportMeshAsObj(vertices, triangles, "/Users/jeremy/Desktop/test.obj");
|
|
||||||
m_isSelfIntersected = true;
|
m_isSelfIntersected = true;
|
||||||
if (removeSelfIntersects) {
|
if (removeSelfIntersects) {
|
||||||
if (!CGAL::Polygon_mesh_processing::remove_self_intersections(*cgalMesh)) {
|
if (!CGAL::Polygon_mesh_processing::remove_self_intersections(*cgalMesh)) {
|
||||||
//qDebug() << "Mesh does self intersect and cann't remove intersections";
|
|
||||||
delete cgalMesh;
|
delete cgalMesh;
|
||||||
cgalMesh = nullptr;
|
cgalMesh = nullptr;
|
||||||
} else {
|
|
||||||
//qDebug() << "Mesh does self intersect but intersections got removed";
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
delete cgalMesh;
|
delete cgalMesh;
|
||||||
cgalMesh = nullptr;
|
cgalMesh = nullptr;
|
||||||
//qDebug() << "Mesh does self intersect";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
qDebug() << "Mesh triangulate failed";
|
|
||||||
delete cgalMesh;
|
|
||||||
cgalMesh = nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,12 @@
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <unordered_map>
|
#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
|
#ifndef M_PI
|
||||||
#define M_PI 3.14159265358979323846
|
#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;
|
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;
|
std::vector<std::vector<size_t>> rings;
|
||||||
for (const auto &face: faces) {
|
for (const auto &face: faces) {
|
||||||
if (face.size() > 3) {
|
if (face.size() > 3) {
|
||||||
|
@ -128,8 +164,10 @@ void nodemesh::triangulate(const std::vector<QVector3D> &vertices, const std::ve
|
||||||
triangles.push_back(newFace);
|
triangles.push_back(newFace);
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "Triangulate failed, ring size:" << fillRing.size();
|
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)
|
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);
|
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);
|
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);
|
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 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,
|
void exportMeshAsObjWithNormals(const std::vector<QVector3D> &vertices, const std::vector<std::vector<size_t>> &faces, const QString &filename,
|
||||||
const std::vector<QVector3D> &triangleVertexNormals);
|
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 trim(std::vector<QVector3D> *vertices, bool normalize=false);
|
||||||
void subdivideFace2D(std::vector<QVector2D> *face);
|
void subdivideFace2D(std::vector<QVector2D> *face);
|
||||||
void chamferFace2D(std::vector<QVector2D> *face);
|
void chamferFace2D(std::vector<QVector2D> *face);
|
||||||
|
bool validatePosition(const QVector3D &position);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue