Fix mesh hole

master
Jeremy Hu 2018-04-15 23:15:29 +08:00
parent 0d4c926476
commit ba61019b5b
11 changed files with 46 additions and 21 deletions

View File

@ -45,7 +45,7 @@ void MeshGenerator::addPreviewRequirement()
void MeshGenerator::addPartPreviewRequirement(const QString &partId) void MeshGenerator::addPartPreviewRequirement(const QString &partId)
{ {
qDebug() << "addPartPreviewRequirement:" << partId; //qDebug() << "addPartPreviewRequirement:" << partId;
m_requirePartPreviewMap.insert(partId); m_requirePartPreviewMap.insert(partId);
if (m_partPreviewRenderMap.find(partId) == m_partPreviewRenderMap.end()) { if (m_partPreviewRenderMap.find(partId) == m_partPreviewRenderMap.end()) {
ModelOfflineRender *render = new ModelOfflineRender; ModelOfflineRender *render = new ModelOfflineRender;
@ -104,13 +104,13 @@ void MeshGenerator::process()
float originZ = valueOfKeyInMapOrEmpty(m_snapshot->canvas, "originZ").toFloat(); float originZ = valueOfKeyInMapOrEmpty(m_snapshot->canvas, "originZ").toFloat();
bool originSettled = false; bool originSettled = false;
if (originX > 0 && originY > 0 && originZ > 0) { if (originX > 0 && originY > 0 && originZ > 0) {
qDebug() << "Use settled origin: " << originX << originY << originZ << " calculated:" << mainProfileMiddleX << mainProfileMiddleY << sideProfileMiddleX; //qDebug() << "Use settled origin: " << originX << originY << originZ << " calculated:" << mainProfileMiddleX << mainProfileMiddleY << sideProfileMiddleX;
mainProfileMiddleX = originX; mainProfileMiddleX = originX;
mainProfileMiddleY = originY; mainProfileMiddleY = originY;
sideProfileMiddleX = originZ; sideProfileMiddleX = originZ;
originSettled = true; originSettled = true;
} else { } else {
qDebug() << "No settled origin, calculated:" << mainProfileMiddleX << mainProfileMiddleY << sideProfileMiddleX; //qDebug() << "No settled origin, calculated:" << mainProfileMiddleX << mainProfileMiddleY << sideProfileMiddleX;
} }
for (const auto &partIdIt: m_snapshot->partIdList) { for (const auto &partIdIt: m_snapshot->partIdList) {
@ -131,7 +131,7 @@ void MeshGenerator::process()
QString partId = valueOfKeyInMapOrEmpty(edgeIt.second, "partId"); QString partId = valueOfKeyInMapOrEmpty(edgeIt.second, "partId");
QString fromNodeId = valueOfKeyInMapOrEmpty(edgeIt.second, "from"); QString fromNodeId = valueOfKeyInMapOrEmpty(edgeIt.second, "from");
QString toNodeId = valueOfKeyInMapOrEmpty(edgeIt.second, "to"); QString toNodeId = valueOfKeyInMapOrEmpty(edgeIt.second, "to");
qDebug() << "Processing edge " << fromNodeId << "<=>" << toNodeId; //qDebug() << "Processing edge " << fromNodeId << "<=>" << toNodeId;
const auto fromIt = m_snapshot->nodes.find(fromNodeId); const auto fromIt = m_snapshot->nodes.find(fromNodeId);
const auto toIt = m_snapshot->nodes.find(toNodeId); const auto toIt = m_snapshot->nodes.find(toNodeId);
if (fromIt == m_snapshot->nodes.end() || toIt == m_snapshot->nodes.end()) if (fromIt == m_snapshot->nodes.end() || toIt == m_snapshot->nodes.end())
@ -149,11 +149,11 @@ void MeshGenerator::process()
float y = (valueOfKeyInMapOrEmpty(fromIt->second, "y").toFloat() - mainProfileMiddleY) / longHeight; float y = (valueOfKeyInMapOrEmpty(fromIt->second, "y").toFloat() - mainProfileMiddleY) / longHeight;
float z = (valueOfKeyInMapOrEmpty(fromIt->second, "z").toFloat() - sideProfileMiddleX) / longHeight; float z = (valueOfKeyInMapOrEmpty(fromIt->second, "z").toFloat() - sideProfileMiddleX) / longHeight;
bmeshFromNodeId = meshlite_bmesh_add_node(meshliteContext, bmeshId, x, y, z, radius); bmeshFromNodeId = meshlite_bmesh_add_node(meshliteContext, bmeshId, x, y, z, radius);
qDebug() << "bmeshId[" << bmeshId << "] add node[" << bmeshFromNodeId << "]" << radius << x << y << z; //qDebug() << "bmeshId[" << bmeshId << "] add node[" << bmeshFromNodeId << "]" << radius << x << y << z;
bmeshNodeMap[fromNodeId] = bmeshFromNodeId; bmeshNodeMap[fromNodeId] = bmeshFromNodeId;
} else { } else {
bmeshFromNodeId = bmeshFromIt->second; bmeshFromNodeId = bmeshFromIt->second;
qDebug() << "bmeshId[" << bmeshId << "] use existed node[" << bmeshFromNodeId << "]"; //qDebug() << "bmeshId[" << bmeshId << "] use existed node[" << bmeshFromNodeId << "]";
} }
int bmeshToNodeId = 0; int bmeshToNodeId = 0;
@ -164,11 +164,11 @@ void MeshGenerator::process()
float y = (valueOfKeyInMapOrEmpty(toIt->second, "y").toFloat() - mainProfileMiddleY) / longHeight; float y = (valueOfKeyInMapOrEmpty(toIt->second, "y").toFloat() - mainProfileMiddleY) / longHeight;
float z = (valueOfKeyInMapOrEmpty(toIt->second, "z").toFloat() - sideProfileMiddleX) / longHeight; float z = (valueOfKeyInMapOrEmpty(toIt->second, "z").toFloat() - sideProfileMiddleX) / longHeight;
bmeshToNodeId = meshlite_bmesh_add_node(meshliteContext, bmeshId, x, y, z, radius); bmeshToNodeId = meshlite_bmesh_add_node(meshliteContext, bmeshId, x, y, z, radius);
qDebug() << "bmeshId[" << bmeshId << "] add node[" << bmeshToNodeId << "]" << radius << x << y << z; //qDebug() << "bmeshId[" << bmeshId << "] add node[" << bmeshToNodeId << "]" << radius << x << y << z;
bmeshNodeMap[toNodeId] = bmeshToNodeId; bmeshNodeMap[toNodeId] = bmeshToNodeId;
} else { } else {
bmeshToNodeId = bmeshToIt->second; bmeshToNodeId = bmeshToIt->second;
qDebug() << "bmeshId[" << bmeshId << "] use existed node[" << bmeshToNodeId << "]"; //qDebug() << "bmeshId[" << bmeshId << "] use existed node[" << bmeshToNodeId << "]";
} }
meshlite_bmesh_add_edge(meshliteContext, bmeshId, bmeshFromNodeId, bmeshToNodeId); meshlite_bmesh_add_edge(meshliteContext, bmeshId, bmeshFromNodeId, bmeshToNodeId);
@ -188,7 +188,7 @@ void MeshGenerator::process()
float y = (valueOfKeyInMapOrEmpty(nodeIt.second, "y").toFloat() - mainProfileMiddleY) / longHeight; float y = (valueOfKeyInMapOrEmpty(nodeIt.second, "y").toFloat() - mainProfileMiddleY) / longHeight;
float z = (valueOfKeyInMapOrEmpty(nodeIt.second, "z").toFloat() - sideProfileMiddleX) / longHeight; float z = (valueOfKeyInMapOrEmpty(nodeIt.second, "z").toFloat() - sideProfileMiddleX) / longHeight;
int bmeshNodeId = meshlite_bmesh_add_node(meshliteContext, bmeshId, x, y, z, radius); int bmeshNodeId = meshlite_bmesh_add_node(meshliteContext, bmeshId, x, y, z, radius);
qDebug() << "bmeshId[" << bmeshId << "] add lonely node[" << bmeshNodeId << "]" << radius << x << y << z; //qDebug() << "bmeshId[" << bmeshId << "] add lonely node[" << bmeshNodeId << "]" << radius << x << y << z;
bmeshNodeMap[nodeIt.first] = bmeshNodeId; bmeshNodeMap[nodeIt.first] = bmeshNodeId;
} }
@ -259,8 +259,8 @@ void MeshGenerator::process()
} else { } else {
mergedMeshId = subdivMeshIds[0]; mergedMeshId = subdivMeshIds[0];
} }
if (mergedMeshId > 0) //if (mergedMeshId > 0)
mergedMeshId = meshlite_combine_coplanar_faces(meshliteContext, mergedMeshId); // mergedMeshId = meshlite_combine_coplanar_faces(meshliteContext, mergedMeshId);
if (mergedMeshId > 0) { if (mergedMeshId > 0) {
int errorCount = 0; int errorCount = 0;
int subdivedMeshId = subdivMesh(meshliteContext, mergedMeshId, &errorCount); int subdivedMeshId = subdivMesh(meshliteContext, mergedMeshId, &errorCount);
@ -283,8 +283,8 @@ void MeshGenerator::process()
mergedMeshId = unionMeshs(meshliteContext, meshIds, &errorCount); mergedMeshId = unionMeshs(meshliteContext, meshIds, &errorCount);
if (errorCount) if (errorCount)
broken = true; broken = true;
else if (mergedMeshId > 0) //else if (mergedMeshId > 0)
mergedMeshId = meshlite_combine_coplanar_faces(meshliteContext, mergedMeshId); // mergedMeshId = meshlite_combine_coplanar_faces(meshliteContext, mergedMeshId);
} else if (meshIds.size() > 0) { } else if (meshIds.size() > 0) {
mergedMeshId = meshIds[0]; mergedMeshId = meshIds[0];
} }

View File

@ -1,3 +1,4 @@
#include <QDebug>
#include "meshutil.h" #include "meshutil.h"
#include "meshlite.h" #include "meshlite.h"
@ -12,6 +13,7 @@
// https://github.com/CGAL/cgal/issues/2875 // https://github.com/CGAL/cgal/issues/2875
// https://doc.cgal.org/latest/Polygon_mesh_processing/Polygon_mesh_processing_2hausdorff_distance_remeshing_example_8cpp-example.html#a3 // https://doc.cgal.org/latest/Polygon_mesh_processing/Polygon_mesh_processing_2hausdorff_distance_remeshing_example_8cpp-example.html#a3
// https://github.com/CGAL/cgal/blob/master/Subdivision_method_3/examples/Subdivision_method_3/CatmullClark_subdivision.cpp // https://github.com/CGAL/cgal/blob/master/Subdivision_method_3/examples/Subdivision_method_3/CatmullClark_subdivision.cpp
// https://doc.cgal.org/latest/Polygon_mesh_processing/index.html#title25
#include <CGAL/Exact_predicates_exact_constructions_kernel.h> #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h> #include <CGAL/Surface_mesh.h>
#include <CGAL/Polygon_mesh_processing/corefinement.h> #include <CGAL/Polygon_mesh_processing/corefinement.h>
@ -146,18 +148,22 @@ int unionMeshs(void *meshliteContext, const std::vector<int> &meshIds, int *erro
std::vector<ExactMesh *> externalMeshs; std::vector<ExactMesh *> externalMeshs;
for (size_t i = 0; i < meshIds.size(); i++) { for (size_t i = 0; i < meshIds.size(); i++) {
int triangledMeshId = meshlite_triangulate(meshliteContext, meshIds[i]); int triangledMeshId = meshlite_triangulate(meshliteContext, meshIds[i]);
if (meshlite_is_triangulated_manifold(meshliteContext, triangledMeshId)) if (!meshlite_is_triangulated_manifold(meshliteContext, triangledMeshId))
externalMeshs.push_back(makeCgalMeshFromMeshlite<ExactKernel>(meshliteContext, triangledMeshId)); qDebug() << "Mesh is not manifold after triangulated:" << triangledMeshId;
externalMeshs.push_back(makeCgalMeshFromMeshlite<ExactKernel>(meshliteContext, triangledMeshId));
} }
if (externalMeshs.size() > 0) { if (externalMeshs.size() > 0) {
ExactMesh *mergedExternalMesh = externalMeshs[0]; ExactMesh *mergedExternalMesh = externalMeshs[0];
for (size_t i = 1; i < externalMeshs.size(); i++) { for (size_t i = 1; i < externalMeshs.size(); i++) {
if (!mergedExternalMesh) if (!mergedExternalMesh) {
qDebug() << "Last union failed, break with remains unprocessed:" << (externalMeshs.size() - i);
break; break;
}
ExactMesh *unionedExternalMesh = NULL; ExactMesh *unionedExternalMesh = NULL;
try { try {
unionedExternalMesh = unionCgalMeshs(mergedExternalMesh, externalMeshs[i]); unionedExternalMesh = unionCgalMeshs(mergedExternalMesh, externalMeshs[i]);
} catch (...) { } catch (...) {
qDebug() << "unionCgalMeshs throw exception";
if (errorCount) if (errorCount)
(*errorCount)++; (*errorCount)++;
} }
@ -165,10 +171,21 @@ int unionMeshs(void *meshliteContext, const std::vector<int> &meshIds, int *erro
if (unionedExternalMesh) { if (unionedExternalMesh) {
delete mergedExternalMesh; delete mergedExternalMesh;
mergedExternalMesh = unionedExternalMesh; mergedExternalMesh = unionedExternalMesh;
} else {
if (errorCount)
(*errorCount)++;
qDebug() << "unionCgalMeshs failed";
} }
} }
if (mergedExternalMesh) { if (mergedExternalMesh) {
int mergedMeshId = makeMeshliteMeshFromCgal<ExactKernel>(meshliteContext, mergedExternalMesh); int mergedMeshId = makeMeshliteMeshFromCgal<ExactKernel>(meshliteContext, mergedExternalMesh);
if (mergedMeshId)
mergedMeshId = fixMeshHoles(meshliteContext, mergedMeshId);
else {
if (errorCount)
(*errorCount)++;
qDebug() << "makeMeshliteMeshFromCgal failed";
}
delete mergedExternalMesh; delete mergedExternalMesh;
return mergedMeshId; return mergedMeshId;
} }
@ -206,8 +223,15 @@ int subdivMesh(void *meshliteContext, int meshId, int *errorCount)
} }
if (simpleMesh) if (simpleMesh)
delete simpleMesh; delete simpleMesh;
if (subdiviedMeshId)
subdiviedMeshId = fixMeshHoles(meshliteContext, subdiviedMeshId);
return subdiviedMeshId; return subdiviedMeshId;
#endif #endif
} }
return meshlite_subdivide(meshliteContext, meshId); return meshlite_subdivide(meshliteContext, meshId);
} }
int fixMeshHoles(void *meshliteContext, int meshId)
{
return meshlite_fix_hole(meshliteContext, meshId);
}

View File

@ -5,5 +5,6 @@
int mergeMeshs(void *meshliteContext, const std::vector<int> &meshIds); int mergeMeshs(void *meshliteContext, const std::vector<int> &meshIds);
int unionMeshs(void *meshliteContext, const std::vector<int> &meshIds, int *errorCount=0); int unionMeshs(void *meshliteContext, const std::vector<int> &meshIds, int *errorCount=0);
int subdivMesh(void *meshliteContext, int meshId, int *errorCount=0); int subdivMesh(void *meshliteContext, int meshId, int *errorCount=0);
int fixMeshHoles(void *meshliteContext, int meshId);
#endif #endif

View File

@ -105,8 +105,6 @@ QImage ModelOfflineRender::toImage(const QSize &size)
image = renderFbo->toImage(); image = renderFbo->toImage();
qDebug() << "Generated image size:" << image.size();
renderFbo->bindDefault(); renderFbo->bindDefault();
delete renderFbo; delete renderFbo;

View File

@ -50,9 +50,9 @@ void SkeletonSnapshot::resolveBoundingBox(QRectF *mainProfile, QRectF *sideProfi
} }
*mainProfile = QRectF(QPointF(left, top), QPointF(right, bottom)); *mainProfile = QRectF(QPointF(left, top), QPointF(right, bottom));
*sideProfile = QRectF(QPointF(zLeft, top), QPointF(zRight, bottom)); *sideProfile = QRectF(QPointF(zLeft, top), QPointF(zRight, bottom));
qDebug() << "resolveBoundingBox left:" << left << "top:" << top << "right:" << right << "bottom:" << bottom << " zLeft:" << zLeft << "zRight:" << zRight; //qDebug() << "resolveBoundingBox left:" << left << "top:" << top << "right:" << right << "bottom:" << bottom << " zLeft:" << zLeft << "zRight:" << zRight;
qDebug() << "mainHeight:" << mainProfile->height() << "mainWidth:" << mainProfile->width(); //qDebug() << "mainHeight:" << mainProfile->height() << "mainWidth:" << mainProfile->width();
qDebug() << "sideHeight:" << sideProfile->height() << "sideWidth:" << sideProfile->width(); //qDebug() << "sideHeight:" << sideProfile->height() << "sideWidth:" << sideProfile->width();
} }

BIN
thirdparty/meshlite/meshlite_unstable_vc14_x64/meshlite.dll vendored Executable file → Normal file

Binary file not shown.

BIN
thirdparty/meshlite/meshlite_unstable_vc14_x64/meshlite.dll.lib vendored Executable file → Normal file

Binary file not shown.

1
thirdparty/meshlite/meshlite_unstable_vc14_x64/meshlite.h vendored Executable file → Normal file
View File

@ -44,6 +44,7 @@ int meshlite_combine_coplanar_faces(void *context, int mesh_id);
int meshlite_trim(void *context, int mesh_id, int normalize); int meshlite_trim(void *context, int mesh_id, int normalize);
int meshlite_mirror_in_x(void *context, int mesh_id, float center_x); int meshlite_mirror_in_x(void *context, int mesh_id, float center_x);
int meshlite_mirror_in_z(void *context, int mesh_id, float center_z); int meshlite_mirror_in_z(void *context, int mesh_id, float center_z);
int meshlite_fix_hole(void *context, int mesh_id);
#ifdef __cplusplus #ifdef __cplusplus
} }

BIN
thirdparty/meshlite/meshlite_unstable_vc14_x86/meshlite.dll vendored Executable file → Normal file

Binary file not shown.

BIN
thirdparty/meshlite/meshlite_unstable_vc14_x86/meshlite.dll.lib vendored Executable file → Normal file

Binary file not shown.

1
thirdparty/meshlite/meshlite_unstable_vc14_x86/meshlite.h vendored Executable file → Normal file
View File

@ -44,6 +44,7 @@ int meshlite_combine_coplanar_faces(void *context, int mesh_id);
int meshlite_trim(void *context, int mesh_id, int normalize); int meshlite_trim(void *context, int mesh_id, int normalize);
int meshlite_mirror_in_x(void *context, int mesh_id, float center_x); int meshlite_mirror_in_x(void *context, int mesh_id, float center_x);
int meshlite_mirror_in_z(void *context, int mesh_id, float center_z); int meshlite_mirror_in_z(void *context, int mesh_id, float center_z);
int meshlite_fix_hole(void *context, int mesh_id);
#ifdef __cplusplus #ifdef __cplusplus
} }