Change subdiv stratege: subdiv after union.
parent
28a95aedee
commit
b95276ec06
15
src/mesh.cpp
15
src/mesh.cpp
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -37,6 +37,7 @@ private:
|
|||
QThread *m_thread;
|
||||
private:
|
||||
void resolveBoundingBox(QRectF *mainProfile, QRectF *sideProfile);
|
||||
static bool enableDebug;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue