Fix mesh hole
parent
0d4c926476
commit
ba61019b5b
|
@ -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];
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -104,8 +104,6 @@ QImage ModelOfflineRender::toImage(const QSize &size)
|
||||||
m_context->functions()->glFlush();
|
m_context->functions()->glFlush();
|
||||||
|
|
||||||
image = renderFbo->toImage();
|
image = renderFbo->toImage();
|
||||||
|
|
||||||
qDebug() << "Generated image size:" << image.size();
|
|
||||||
|
|
||||||
renderFbo->bindDefault();
|
renderFbo->bindDefault();
|
||||||
delete renderFbo;
|
delete renderFbo;
|
||||||
|
|
|
@ -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
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
BIN
thirdparty/meshlite/meshlite_unstable_vc14_x64/meshlite.dll.lib
vendored
Executable file → Normal file
Binary file not shown.
|
@ -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
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
BIN
thirdparty/meshlite/meshlite_unstable_vc14_x86/meshlite.dll.lib
vendored
Executable file → Normal file
Binary file not shown.
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue