Improve intermediate nodes generation
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).master
parent
6cd42da44e
commit
aec5acd793
|
@ -33,3 +33,4 @@ Satish Goda <https://github.com/SatishGodaPearl>
|
|||
Sawm Fawk <https://twitter.com/sawmfawk>
|
||||
Erlend Sogge Heggen <https://twitter.com/erlend_sh>
|
||||
Michael Nowak <https://dust3d.discourse.group/u/mcnnowak>
|
||||
Nico J. Dolloso <https://twitter.com/nicodoll>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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<QVector3D> &sourceVertices, const std::vector<std::vector<size_t>> &sourceFaces,
|
||||
std::vector<QVector3D> *destVertices, std::vector<std::vector<size_t>> *destFaces);
|
||||
|
|
|
@ -6,6 +6,11 @@
|
|||
namespace nodemesh
|
||||
{
|
||||
|
||||
void Modifier::enableIntermediateAddition()
|
||||
{
|
||||
m_intermediateAdditionEnabled = true;
|
||||
}
|
||||
|
||||
size_t Modifier::addNode(const QVector3D &position, float radius, const std::vector<QVector2D> &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) {
|
||||
|
|
|
@ -31,6 +31,7 @@ public:
|
|||
size_t addEdge(size_t firstNodeIndex, size_t secondNodeIndex);
|
||||
void subdivide();
|
||||
void roundEnd();
|
||||
void enableIntermediateAddition();
|
||||
const std::vector<Node> &nodes();
|
||||
const std::vector<Edge> &edges();
|
||||
void finalize();
|
||||
|
@ -39,6 +40,7 @@ private:
|
|||
|
||||
std::vector<Node> m_nodes;
|
||||
std::vector<Edge> m_edges;
|
||||
bool m_intermediateAdditionEnabled = false;
|
||||
|
||||
void createIntermediateNode(const Node &firstNode, const Node &secondNode, float factor, Node *resultNode);
|
||||
float averageCutTemplateEdgeLength(const std::vector<QVector2D> &cutTemplate);
|
||||
|
|
Loading…
Reference in New Issue