From aec5acd79320582c30fa5fd4e3e6fde746d0ad8b Mon Sep 17 00:00:00 2001 From: Jeremy Hu Date: Sat, 20 Jul 2019 12:12:24 +0930 Subject: [PATCH] Improve intermediate nodes generation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added Intermediates nodes sometimes will make the whole part’s mesh failed to generate. This commit add a fallback option, when mesh failed to generate, the generator will try again without the intermediate nodes added. This feature is inspired from Nico J. Dolloso’s model (https://twitter.com/nicodoll). --- CONTRIBUTORS | 1 + src/meshgenerator.cpp | 35 ++++++++++++----------- src/meshgenerator.h | 2 +- thirdparty/nodemesh/nodemesh/modifier.cpp | 7 +++++ thirdparty/nodemesh/nodemesh/modifier.h | 2 ++ 5 files changed, 29 insertions(+), 18 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 97719cd2..4772daf8 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -33,3 +33,4 @@ Satish Goda Sawm Fawk Erlend Sogge Heggen Michael Nowak +Nico J. Dolloso diff --git a/src/meshgenerator.cpp b/src/meshgenerator.cpp index 8eb8bb46..8057b2b9 100644 --- a/src/meshgenerator.cpp +++ b/src/meshgenerator.cpp @@ -323,7 +323,7 @@ void MeshGenerator::cutFaceStringToCutTemplate(const QString &cutFaceString, std } } -nodemesh::Combiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdString) +nodemesh::Combiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdString, bool *hasError, bool addIntermediateNodes) { auto findPart = m_snapshot->parts.find(partIdString); if (findPart == m_snapshot->parts.end()) { @@ -467,6 +467,9 @@ nodemesh::Combiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdSt nodemesh::Modifier *modifier = new nodemesh::Modifier; + if (addIntermediateNodes) + modifier->enableIntermediateAddition(); + QString mirroredPartIdString; QUuid mirroredPartId; if (xMirrored) { @@ -561,20 +564,6 @@ nodemesh::Combiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdSt builder->addEdge(edge.firstNodeIndex, edge.secondNodeIndex); bool buildSucceed = builder->build(); - //for (size_t i = 0; i < modifier->nodes().size(); ++i) { - // const auto &node = modifier->nodes()[i]; - // if (!node.isOriginal) - // continue; - // const QString &nodeIdString = nodeIndexToIdStringMap[node.originNodeIndex]; - // const nodemesh::Builder::CutFaceTransform *cutFaceTransform = builder->nodeAdjustableCutFaceTransform(builderNodeIndices[i]); - // if (nullptr != cutFaceTransform && - // PartTarget::Model == target) { - // QUuid nodeId = QUuid(nodeIdString); - // m_cutFaceTransforms->insert({nodeId, *cutFaceTransform}); - // m_nodesCutFaces->insert({nodeId, cutTemplateMapByName}); - // } - //} - partCache.vertices = builder->generatedVertices(); partCache.faces = builder->generatedFaces(); for (size_t i = 0; i < partCache.vertices.size(); ++i) { @@ -633,6 +622,7 @@ nodemesh::Combiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdSt qDebug() << "Mesh build failed"; } + delete m_partPreviewMeshes[partId]; m_partPreviewMeshes[partId] = nullptr; m_generatedPreviewPartIds.insert(partId); @@ -695,7 +685,8 @@ nodemesh::Combiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdSt } if (hasMeshError && target == PartTarget::Model) { - m_isSucceed = false; + *hasError = true; + //m_isSucceed = false; } return mesh; @@ -789,7 +780,17 @@ nodemesh::Combiner::Mesh *MeshGenerator::combineComponentMesh(const QString &com QString linkDataType = valueOfKeyInMapOrEmpty(*component, "linkDataType"); if ("partId" == linkDataType) { QString partIdString = valueOfKeyInMapOrEmpty(*component, "linkData"); - mesh = combinePartMesh(partIdString); + bool hasError = false; + mesh = combinePartMesh(partIdString, &hasError); + if (hasError) { + delete mesh; + hasError = false; + qDebug() << "Try combine part again without adding intermediate nodes"; + mesh = combinePartMesh(partIdString, &hasError, false); + if (hasError) { + m_isSucceed = false; + } + } const auto &partCache = m_cacheContext->parts[partIdString]; for (const auto &vertex: partCache.vertices) diff --git a/src/meshgenerator.h b/src/meshgenerator.h index 34edf9c7..9e1ae6b7 100644 --- a/src/meshgenerator.h +++ b/src/meshgenerator.h @@ -100,7 +100,7 @@ private: bool checkIsPartDirty(const QString &partIdString); bool checkIsPartDependencyDirty(const QString &partIdString); void checkDirtyFlags(); - nodemesh::Combiner::Mesh *combinePartMesh(const QString &partIdString); + nodemesh::Combiner::Mesh *combinePartMesh(const QString &partIdString, bool *hasError, bool addIntermediateNodes=true); nodemesh::Combiner::Mesh *combineComponentMesh(const QString &componentIdString, CombineMode *combineMode); void makeXmirror(const std::vector &sourceVertices, const std::vector> &sourceFaces, std::vector *destVertices, std::vector> *destFaces); diff --git a/thirdparty/nodemesh/nodemesh/modifier.cpp b/thirdparty/nodemesh/nodemesh/modifier.cpp index 26b3e756..51d62e75 100644 --- a/thirdparty/nodemesh/nodemesh/modifier.cpp +++ b/thirdparty/nodemesh/nodemesh/modifier.cpp @@ -6,6 +6,11 @@ namespace nodemesh { +void Modifier::enableIntermediateAddition() +{ + m_intermediateAdditionEnabled = true; +} + size_t Modifier::addNode(const QVector3D &position, float radius, const std::vector &cutTemplate, float cutRotation) { size_t nodeIndex = m_nodes.size(); @@ -100,6 +105,8 @@ void Modifier::roundEnd() void Modifier::finalize() { + if (!m_intermediateAdditionEnabled) + return; auto oldEdges = m_edges; m_edges.clear(); for (const auto &edge: oldEdges) { diff --git a/thirdparty/nodemesh/nodemesh/modifier.h b/thirdparty/nodemesh/nodemesh/modifier.h index 0f1f4d2a..92a96db4 100644 --- a/thirdparty/nodemesh/nodemesh/modifier.h +++ b/thirdparty/nodemesh/nodemesh/modifier.h @@ -31,6 +31,7 @@ public: size_t addEdge(size_t firstNodeIndex, size_t secondNodeIndex); void subdivide(); void roundEnd(); + void enableIntermediateAddition(); const std::vector &nodes(); const std::vector &edges(); void finalize(); @@ -39,6 +40,7 @@ private: std::vector m_nodes; std::vector m_edges; + bool m_intermediateAdditionEnabled = false; void createIntermediateNode(const Node &firstNode, const Node &secondNode, float factor, Node *resultNode); float averageCutTemplateEdgeLength(const std::vector &cutTemplate);