Change subdiv stratege: subdiv after union.

master
Jeremy Hu 2018-04-11 14:15:11 +08:00
parent 28a95aedee
commit b95276ec06
6 changed files with 92 additions and 38 deletions

View File

@ -5,11 +5,12 @@
#define MAX_VERTICES_PER_FACE 100
Mesh::Mesh(void *meshlite, int meshId) :
Mesh::Mesh(void *meshlite, int meshId, bool broken) :
m_triangleVertices(NULL),
m_triangleVertexCount(0),
m_edgeVertices(NULL),
m_edgeVertexCount(0)
m_edgeVertexCount(0),
m_broken(broken)
{
int edgeVertexPositionCount = meshlite_get_vertex_count(meshlite, meshId);
GLfloat *edgeVertexPositions = new GLfloat[edgeVertexPositionCount * 3];
@ -82,6 +83,11 @@ Mesh::Mesh(void *meshlite, int meshId) :
float modelR = Theme::white.redF();
float modelG = Theme::white.greenF();
float modelB = Theme::white.blueF();
if (m_broken) {
modelR = 1.0;
modelG = 1.0;
modelB = 1.0;
}
m_triangleVertexCount = triangleCount * 3;
m_triangleVertices = new Vertex[m_triangleVertexCount * 3];
for (int i = 0; i < triangleCount; i++) {
@ -119,6 +125,11 @@ Mesh::~Mesh()
m_triangleVertexCount = 0;
}
void Mesh::setBroken(bool broken)
{
m_broken = broken;
}
const std::vector<QVector3D> &Mesh::vertices()
{
return m_vertices;

View File

@ -24,7 +24,7 @@ typedef struct
class Mesh
{
public:
Mesh(void *meshlite, int meshId);
Mesh(void *meshlite, int meshId, bool broken=false);
~Mesh();
Vertex *triangleVertices();
int triangleVertexCount();
@ -32,6 +32,7 @@ public:
int edgeVertexCount();
const std::vector<QVector3D> &vertices();
const std::vector<std::vector<int>> &faces();
void setBroken(bool broken);
private:
Vertex *m_triangleVertices;
int m_triangleVertexCount;
@ -39,6 +40,7 @@ private:
int m_edgeVertexCount;
std::vector<QVector3D> m_vertices;
std::vector<std::vector<int>> m_faces;
bool m_broken;
};
#endif

View File

@ -8,6 +8,8 @@
#include "meshutil.h"
#include "theme.h"
bool MeshGenerator::enableDebug = false;
MeshGenerator::MeshGenerator(SkeletonSnapshot *snapshot, QThread *thread) :
m_snapshot(snapshot),
m_mesh(nullptr),
@ -75,34 +77,46 @@ QImage *MeshGenerator::takePartPreview(const QString &partId)
void MeshGenerator::resolveBoundingBox(QRectF *mainProfile, QRectF *sideProfile)
{
float left = -1;
float right = -1;
float top = -1;
float bottom = -1;
float zLeft = -1;
float zRight = -1;
float left = 0;
bool leftFirstTime = true;
float right = 0;
bool rightFirstTime = true;
float top = 0;
bool topFirstTime = true;
float bottom = 0;
bool bottomFirstTime = true;
float zLeft = 0;
bool zLeftFirstTime = true;
float zRight = 0;
bool zRightFirstTime = true;
for (const auto &nodeIt: m_snapshot->nodes) {
float radius = valueOfKeyInMapOrEmpty(nodeIt.second, "radius").toFloat();
float x = valueOfKeyInMapOrEmpty(nodeIt.second, "x").toFloat();
float y = valueOfKeyInMapOrEmpty(nodeIt.second, "y").toFloat();
float z = valueOfKeyInMapOrEmpty(nodeIt.second, "z").toFloat();
if (left < 0 || x - radius < left) {
if (leftFirstTime || x - radius < left) {
left = x - radius;
leftFirstTime = false;
}
if (top < 0 || y - radius < top) {
if (topFirstTime || y - radius < top) {
top = y - radius;
topFirstTime = false;
}
if (x + radius > right) {
if (rightFirstTime > right) {
right = x + radius;
rightFirstTime = false;
}
if (y + radius > bottom) {
if (bottomFirstTime > bottom) {
bottom = y + radius;
bottomFirstTime = false;
}
if (zLeft < 0 || z - radius < zLeft) {
if (zLeftFirstTime || z - radius < zLeft) {
zLeft = z - radius;
zLeftFirstTime = false;
}
if (z + radius > zRight) {
if (zRightFirstTime > zRight) {
zRight = z + radius;
zRightFirstTime = false;
}
}
*mainProfile = QRectF(left, top, right - left, bottom - top);
@ -117,7 +131,6 @@ void MeshGenerator::process()
void *meshliteContext = meshlite_create_context();
std::map<QString, int> partBmeshMap;
std::map<QString, int> bmeshNodeMap;
bool hasSubdiv = false;
QRectF mainProfile, sideProfile;
resolveBoundingBox(&mainProfile, &sideProfile);
@ -132,6 +145,8 @@ void MeshGenerator::process()
for (const auto &partIdIt: m_snapshot->partIdList) {
int bmeshId = meshlite_bmesh_create(meshliteContext);
if (MeshGenerator::enableDebug)
meshlite_bmesh_enable_debug(meshliteContext, bmeshId, 1);
partBmeshMap[partIdIt] = bmeshId;
}
@ -200,39 +215,65 @@ void MeshGenerator::process()
bmeshNodeMap[nodeIt.first] = bmeshNodeId;
}
std::map<QString, int> partMeshMap;
std::vector<int> meshIds;
std::vector<int> subdivMeshIds;
for (const auto &partIdIt: m_snapshot->partIdList) {
const auto part = m_snapshot->parts.find(partIdIt);
int bmeshId = partBmeshMap[partIdIt];
int meshId = meshlite_bmesh_generate_mesh(meshliteContext, bmeshId, 0);
if (isTrueValueString(part->second["subdived"])) {
int subdivedMeshId = subdivMesh(meshliteContext, meshId);
if (subdivedMeshId > 0) {
meshId = subdivedMeshId;
hasSubdiv = true;
}
}
int meshId = meshlite_bmesh_generate_mesh(meshliteContext, bmeshId);
bool subdived = isTrueValueString(part->second["subdived"]);
if (m_requirePartPreviewMap.find(partIdIt) != m_requirePartPreviewMap.end()) {
ModelOfflineRender *render = m_partPreviewRenderMap[partIdIt];
int trimedMeshId = meshlite_trim(meshliteContext, meshId, 1);
if (subdived) {
int subdivedMeshId = subdivMesh(meshliteContext, trimedMeshId);
if (subdivedMeshId > 0) {
trimedMeshId = subdivedMeshId;
}
}
render->updateMesh(new Mesh(meshliteContext, trimedMeshId));
QImage *image = new QImage(render->toImage(QSize(Theme::previewImageSize, Theme::previewImageSize)));
m_partPreviewMap[partIdIt] = image;
}
int triangulatedMeshId = meshlite_triangulate(meshliteContext, meshId);
meshIds.push_back(triangulatedMeshId);
if (subdived)
subdivMeshIds.push_back(meshId);
else
meshIds.push_back(meshId);
}
bool broken = false;
if (!subdivMeshIds.empty()) {
int mergedMeshId = 0;
int errorCount = 0;
mergedMeshId = unionMeshs(meshliteContext, subdivMeshIds, &errorCount);
if (errorCount)
broken = true;
else if (mergedMeshId > 0)
mergedMeshId = meshlite_combine_coplanar_faces(meshliteContext, mergedMeshId);
if (mergedMeshId > 0) {
int subdivedMeshId = subdivMesh(meshliteContext, mergedMeshId);
if (subdivedMeshId > 0)
mergedMeshId = subdivedMeshId;
else
broken = true;
}
if (mergedMeshId > 0)
meshIds.push_back(mergedMeshId);
else
broken = true;
}
int mergedMeshId = 0;
if (meshIds.size() > 1) {
mergedMeshId = unionMeshs(meshliteContext, meshIds);
int errorCount = 0;
mergedMeshId = unionMeshs(meshliteContext, meshIds, &errorCount);
if (errorCount)
broken = true;
else if (mergedMeshId > 0)
mergedMeshId = meshlite_combine_coplanar_faces(meshliteContext, mergedMeshId);
} else if (meshIds.size() > 0) {
mergedMeshId = meshIds[0];
}
if (mergedMeshId > 0 && !hasSubdiv) {
mergedMeshId = meshlite_combine_coplanar_faces(meshliteContext, mergedMeshId);
}
if (mergedMeshId > 0) {
if (m_requirePreview) {
@ -241,7 +282,7 @@ void MeshGenerator::process()
m_preview = image;
}
int trimedMeshId = meshlite_trim(meshliteContext, mergedMeshId, 1);
m_mesh = new Mesh(meshliteContext, trimedMeshId);
m_mesh = new Mesh(meshliteContext, trimedMeshId, broken);
}
if (m_previewRender) {

View File

@ -37,6 +37,7 @@ private:
QThread *m_thread;
private:
void resolveBoundingBox(QRectF *mainProfile, QRectF *sideProfile);
static bool enableDebug;
};
#endif

View File

@ -139,7 +139,7 @@ ExactMesh *unionCgalMeshs(ExactMesh *first, ExactMesh *second)
#endif
int unionMeshs(void *meshliteContext, const std::vector<int> &meshIds)
int unionMeshs(void *meshliteContext, const std::vector<int> &meshIds, int *errorCount)
{
#if USE_CGAL == 1
CGAL::set_error_behaviour(CGAL::THROW_EXCEPTION);
@ -158,14 +158,13 @@ int unionMeshs(void *meshliteContext, const std::vector<int> &meshIds)
try {
unionedExternalMesh = unionCgalMeshs(mergedExternalMesh, externalMeshs[i]);
} catch (...) {
// ignore;
if (errorCount)
(*errorCount)++;
}
delete externalMeshs[i];
if (unionedExternalMesh) {
delete mergedExternalMesh;
mergedExternalMesh = unionedExternalMesh;
} else {
// TOOD:
}
}
if (mergedExternalMesh) {
@ -199,7 +198,7 @@ int subdivMesh(void *meshliteContext, int meshId)
// return makeMeshliteMeshFromCgal<SimpleKernel>(meshliteContext, simpleMesh);
//#else
if (0 == meshlite_is_triangulated_manifold(meshliteContext, triangulatedMeshId)) {
return meshId;
return 0;
}
return meshlite_subdivide(meshliteContext, meshId);
//#endif

View File

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