Show part preview in red color when there is self intersection.
parent
b86837b4b0
commit
160d2aae5e
|
@ -181,6 +181,8 @@ nodemesh::Combiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdSt
|
||||||
partCache.outcomeNodeVertices.clear();
|
partCache.outcomeNodeVertices.clear();
|
||||||
partCache.vertices.clear();
|
partCache.vertices.clear();
|
||||||
partCache.faces.clear();
|
partCache.faces.clear();
|
||||||
|
partCache.previewTriangles.clear();
|
||||||
|
partCache.isSucceed = false;
|
||||||
delete partCache.mesh;
|
delete partCache.mesh;
|
||||||
partCache.mesh = nullptr;
|
partCache.mesh = nullptr;
|
||||||
|
|
||||||
|
@ -376,30 +378,39 @@ nodemesh::Combiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdSt
|
||||||
m_partPreviewMeshes[partId] = nullptr;
|
m_partPreviewMeshes[partId] = nullptr;
|
||||||
m_generatedPreviewPartIds.insert(partId);
|
m_generatedPreviewPartIds.insert(partId);
|
||||||
|
|
||||||
|
std::vector<QVector3D> partPreviewVertices;
|
||||||
|
QColor partPreviewColor = partColor;
|
||||||
if (nullptr != mesh) {
|
if (nullptr != mesh) {
|
||||||
partCache.mesh = new nodemesh::Combiner::Mesh(*mesh);
|
partCache.mesh = new nodemesh::Combiner::Mesh(*mesh);
|
||||||
|
mesh->fetch(partPreviewVertices, partCache.previewTriangles);
|
||||||
std::vector<QVector3D> partPreviewVertices;
|
partCache.isSucceed = true;
|
||||||
std::vector<std::vector<size_t>> partPreviewTriangles;
|
}
|
||||||
mesh->fetch(partPreviewVertices, partPreviewTriangles);
|
if (partCache.previewTriangles.empty()) {
|
||||||
nodemesh::trim(&partPreviewVertices, true);
|
partPreviewVertices = partCache.vertices;
|
||||||
std::vector<QVector3D> partPreviewTriangleNormals;
|
nodemesh::triangulate(partPreviewVertices, partCache.faces, partCache.previewTriangles);
|
||||||
for (const auto &face: partPreviewTriangles) {
|
partPreviewColor = Qt::red;
|
||||||
partPreviewTriangleNormals.push_back(QVector3D::normal(
|
partCache.isSucceed = false;
|
||||||
partPreviewVertices[face[0]],
|
}
|
||||||
partPreviewVertices[face[1]],
|
|
||||||
partPreviewVertices[face[2]]
|
nodemesh::trim(&partPreviewVertices, true);
|
||||||
));
|
std::vector<QVector3D> partPreviewTriangleNormals;
|
||||||
}
|
for (const auto &face: partCache.previewTriangles) {
|
||||||
std::vector<std::vector<QVector3D>> partPreviewTriangleVertexNormals;
|
partPreviewTriangleNormals.push_back(QVector3D::normal(
|
||||||
generateSmoothTriangleVertexNormals(partPreviewVertices,
|
partPreviewVertices[face[0]],
|
||||||
partPreviewTriangles,
|
partPreviewVertices[face[1]],
|
||||||
partPreviewTriangleNormals,
|
partPreviewVertices[face[2]]
|
||||||
&partPreviewTriangleVertexNormals);
|
));
|
||||||
|
}
|
||||||
|
std::vector<std::vector<QVector3D>> partPreviewTriangleVertexNormals;
|
||||||
|
generateSmoothTriangleVertexNormals(partPreviewVertices,
|
||||||
|
partCache.previewTriangles,
|
||||||
|
partPreviewTriangleNormals,
|
||||||
|
&partPreviewTriangleVertexNormals);
|
||||||
|
if (!partCache.previewTriangles.empty()) {
|
||||||
m_partPreviewMeshes[partId] = new MeshLoader(partPreviewVertices,
|
m_partPreviewMeshes[partId] = new MeshLoader(partPreviewVertices,
|
||||||
partPreviewTriangles,
|
partCache.previewTriangles,
|
||||||
partPreviewTriangleVertexNormals,
|
partPreviewTriangleVertexNormals,
|
||||||
partColor);
|
partPreviewColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete builder;
|
delete builder;
|
||||||
|
@ -815,49 +826,76 @@ void MeshGenerator::generate()
|
||||||
} while (affectedNum > 0);
|
} while (affectedNum > 0);
|
||||||
qDebug() << "Total weld affected triangles:" << totalAffectedNum;
|
qDebug() << "Total weld affected triangles:" << totalAffectedNum;
|
||||||
|
|
||||||
std::vector<QVector3D> combinedFacesNormals;
|
|
||||||
for (const auto &face: combinedFaces) {
|
|
||||||
combinedFacesNormals.push_back(QVector3D::normal(
|
|
||||||
combinedVertices[face[0]],
|
|
||||||
combinedVertices[face[1]],
|
|
||||||
combinedVertices[face[2]]
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
recoverQuads(combinedVertices, combinedFaces, componentCache.sharedQuadEdges, m_outcome->triangleAndQuads);
|
recoverQuads(combinedVertices, combinedFaces, componentCache.sharedQuadEdges, m_outcome->triangleAndQuads);
|
||||||
|
|
||||||
m_outcome->nodes = componentCache.outcomeNodes;
|
m_outcome->nodes = componentCache.outcomeNodes;
|
||||||
m_outcome->nodeVertices = componentCache.outcomeNodeVertices;
|
m_outcome->nodeVertices = componentCache.outcomeNodeVertices;
|
||||||
m_outcome->vertices = combinedVertices;
|
m_outcome->vertices = combinedVertices;
|
||||||
m_outcome->triangles = combinedFaces;
|
m_outcome->triangles = combinedFaces;
|
||||||
m_outcome->triangleNormals = combinedFacesNormals;
|
}
|
||||||
|
|
||||||
|
auto postprocessOutcome = [](Outcome *outcome) {
|
||||||
|
std::vector<QVector3D> combinedFacesNormals;
|
||||||
|
for (const auto &face: outcome->triangles) {
|
||||||
|
combinedFacesNormals.push_back(QVector3D::normal(
|
||||||
|
outcome->vertices[face[0]],
|
||||||
|
outcome->vertices[face[1]],
|
||||||
|
outcome->vertices[face[2]]
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
outcome->triangleNormals = combinedFacesNormals;
|
||||||
|
|
||||||
std::vector<std::pair<QUuid, QUuid>> sourceNodes;
|
std::vector<std::pair<QUuid, QUuid>> sourceNodes;
|
||||||
triangleSourceNodeResolve(*m_outcome, sourceNodes);
|
triangleSourceNodeResolve(*outcome, sourceNodes);
|
||||||
m_outcome->setTriangleSourceNodes(sourceNodes);
|
outcome->setTriangleSourceNodes(sourceNodes);
|
||||||
|
|
||||||
std::map<std::pair<QUuid, QUuid>, QColor> sourceNodeToColorMap;
|
std::map<std::pair<QUuid, QUuid>, QColor> sourceNodeToColorMap;
|
||||||
for (const auto &node: m_outcome->nodes)
|
for (const auto &node: outcome->nodes)
|
||||||
sourceNodeToColorMap.insert({{node.partId, node.nodeId}, node.color});
|
sourceNodeToColorMap.insert({{node.partId, node.nodeId}, node.color});
|
||||||
|
|
||||||
m_outcome->triangleColors.resize(m_outcome->triangles.size(), Qt::white);
|
outcome->triangleColors.resize(outcome->triangles.size(), Qt::white);
|
||||||
const std::vector<std::pair<QUuid, QUuid>> *triangleSourceNodes = m_outcome->triangleSourceNodes();
|
const std::vector<std::pair<QUuid, QUuid>> *triangleSourceNodes = outcome->triangleSourceNodes();
|
||||||
if (nullptr != triangleSourceNodes) {
|
if (nullptr != triangleSourceNodes) {
|
||||||
for (size_t triangleIndex = 0; triangleIndex < m_outcome->triangles.size(); triangleIndex++) {
|
for (size_t triangleIndex = 0; triangleIndex < outcome->triangles.size(); triangleIndex++) {
|
||||||
const auto &source = (*triangleSourceNodes)[triangleIndex];
|
const auto &source = (*triangleSourceNodes)[triangleIndex];
|
||||||
m_outcome->triangleColors[triangleIndex] = sourceNodeToColorMap[source];
|
outcome->triangleColors[triangleIndex] = sourceNodeToColorMap[source];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::vector<QVector3D>> triangleVertexNormals;
|
std::vector<std::vector<QVector3D>> triangleVertexNormals;
|
||||||
generateSmoothTriangleVertexNormals(combinedVertices,
|
generateSmoothTriangleVertexNormals(outcome->vertices,
|
||||||
combinedFaces,
|
outcome->triangles,
|
||||||
combinedFacesNormals,
|
outcome->triangleNormals,
|
||||||
&triangleVertexNormals);
|
&triangleVertexNormals);
|
||||||
m_outcome->setTriangleVertexNormals(triangleVertexNormals);
|
outcome->setTriangleVertexNormals(triangleVertexNormals);
|
||||||
|
};
|
||||||
m_resultMesh = new MeshLoader(*m_outcome);
|
|
||||||
|
/*
|
||||||
|
Outcome *previewOutcome = new Outcome(*m_outcome);
|
||||||
|
for (const auto &partCache: m_cacheContext->parts) {
|
||||||
|
if (partCache.second.isSucceed)
|
||||||
|
continue;
|
||||||
|
size_t oldVerticesCount = previewOutcome->vertices.size();
|
||||||
|
for (const auto &vertex: partCache.second.vertices) {
|
||||||
|
previewOutcome->vertices.push_back(vertex);
|
||||||
|
}
|
||||||
|
for (const auto &face: partCache.second.previewTriangles) {
|
||||||
|
std::vector<size_t> newFace = face;
|
||||||
|
for (auto &index: newFace)
|
||||||
|
index += oldVerticesCount;
|
||||||
|
previewOutcome->triangles.push_back(newFace);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
postprocessOutcome(previewOutcome);
|
||||||
|
m_resultMesh = new MeshLoader(*previewOutcome);
|
||||||
|
delete previewOutcome;
|
||||||
|
*/
|
||||||
|
|
||||||
|
postprocessOutcome(m_outcome);
|
||||||
|
|
||||||
|
m_resultMesh = new MeshLoader(*m_outcome);
|
||||||
|
|
||||||
delete combinedMesh;
|
delete combinedMesh;
|
||||||
|
|
||||||
if (needDeleteCacheContext) {
|
if (needDeleteCacheContext) {
|
||||||
|
|
|
@ -22,6 +22,8 @@ public:
|
||||||
std::vector<std::vector<size_t>> faces;
|
std::vector<std::vector<size_t>> faces;
|
||||||
std::vector<OutcomeNode> outcomeNodes;
|
std::vector<OutcomeNode> outcomeNodes;
|
||||||
std::vector<std::pair<QVector3D, std::pair<QUuid, QUuid>>> outcomeNodeVertices;
|
std::vector<std::pair<QVector3D, std::pair<QUuid, QUuid>>> outcomeNodeVertices;
|
||||||
|
std::vector<std::vector<size_t>> previewTriangles;
|
||||||
|
bool isSucceed = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GeneratedComponent
|
class GeneratedComponent
|
||||||
|
@ -95,7 +97,7 @@ private:
|
||||||
nodemesh::Combiner::Mesh *combineTwoMeshes(const nodemesh::Combiner::Mesh &first, const nodemesh::Combiner::Mesh &second,
|
nodemesh::Combiner::Mesh *combineTwoMeshes(const nodemesh::Combiner::Mesh &first, const nodemesh::Combiner::Mesh &second,
|
||||||
nodemesh::Combiner::Method method,
|
nodemesh::Combiner::Method method,
|
||||||
bool recombine=true);
|
bool recombine=true);
|
||||||
void generateSmoothTriangleVertexNormals(const std::vector<QVector3D> &vertices, const std::vector<std::vector<size_t>> &triangles,
|
static void generateSmoothTriangleVertexNormals(const std::vector<QVector3D> &vertices, const std::vector<std::vector<size_t>> &triangles,
|
||||||
const std::vector<QVector3D> &triangleNormals,
|
const std::vector<QVector3D> &triangleNormals,
|
||||||
std::vector<std::vector<QVector3D>> *triangleVertexNormals);
|
std::vector<std::vector<QVector3D>> *triangleVertexNormals);
|
||||||
const std::map<QString, QString> *findComponent(const QString &componentIdString);
|
const std::map<QString, QString> *findComponent(const QString &componentIdString);
|
||||||
|
|
Loading…
Reference in New Issue