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>
|
Sawm Fawk <https://twitter.com/sawmfawk>
|
||||||
Erlend Sogge Heggen <https://twitter.com/erlend_sh>
|
Erlend Sogge Heggen <https://twitter.com/erlend_sh>
|
||||||
Michael Nowak <https://dust3d.discourse.group/u/mcnnowak>
|
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);
|
auto findPart = m_snapshot->parts.find(partIdString);
|
||||||
if (findPart == m_snapshot->parts.end()) {
|
if (findPart == m_snapshot->parts.end()) {
|
||||||
|
@ -467,6 +467,9 @@ nodemesh::Combiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdSt
|
||||||
|
|
||||||
nodemesh::Modifier *modifier = new nodemesh::Modifier;
|
nodemesh::Modifier *modifier = new nodemesh::Modifier;
|
||||||
|
|
||||||
|
if (addIntermediateNodes)
|
||||||
|
modifier->enableIntermediateAddition();
|
||||||
|
|
||||||
QString mirroredPartIdString;
|
QString mirroredPartIdString;
|
||||||
QUuid mirroredPartId;
|
QUuid mirroredPartId;
|
||||||
if (xMirrored) {
|
if (xMirrored) {
|
||||||
|
@ -561,20 +564,6 @@ nodemesh::Combiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdSt
|
||||||
builder->addEdge(edge.firstNodeIndex, edge.secondNodeIndex);
|
builder->addEdge(edge.firstNodeIndex, edge.secondNodeIndex);
|
||||||
bool buildSucceed = builder->build();
|
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.vertices = builder->generatedVertices();
|
||||||
partCache.faces = builder->generatedFaces();
|
partCache.faces = builder->generatedFaces();
|
||||||
for (size_t i = 0; i < partCache.vertices.size(); ++i) {
|
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";
|
qDebug() << "Mesh build failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete m_partPreviewMeshes[partId];
|
||||||
m_partPreviewMeshes[partId] = nullptr;
|
m_partPreviewMeshes[partId] = nullptr;
|
||||||
m_generatedPreviewPartIds.insert(partId);
|
m_generatedPreviewPartIds.insert(partId);
|
||||||
|
|
||||||
|
@ -695,7 +685,8 @@ nodemesh::Combiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdSt
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasMeshError && target == PartTarget::Model) {
|
if (hasMeshError && target == PartTarget::Model) {
|
||||||
m_isSucceed = false;
|
*hasError = true;
|
||||||
|
//m_isSucceed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mesh;
|
return mesh;
|
||||||
|
@ -789,7 +780,17 @@ nodemesh::Combiner::Mesh *MeshGenerator::combineComponentMesh(const QString &com
|
||||||
QString linkDataType = valueOfKeyInMapOrEmpty(*component, "linkDataType");
|
QString linkDataType = valueOfKeyInMapOrEmpty(*component, "linkDataType");
|
||||||
if ("partId" == linkDataType) {
|
if ("partId" == linkDataType) {
|
||||||
QString partIdString = valueOfKeyInMapOrEmpty(*component, "linkData");
|
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];
|
const auto &partCache = m_cacheContext->parts[partIdString];
|
||||||
for (const auto &vertex: partCache.vertices)
|
for (const auto &vertex: partCache.vertices)
|
||||||
|
|
|
@ -100,7 +100,7 @@ private:
|
||||||
bool checkIsPartDirty(const QString &partIdString);
|
bool checkIsPartDirty(const QString &partIdString);
|
||||||
bool checkIsPartDependencyDirty(const QString &partIdString);
|
bool checkIsPartDependencyDirty(const QString &partIdString);
|
||||||
void checkDirtyFlags();
|
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);
|
nodemesh::Combiner::Mesh *combineComponentMesh(const QString &componentIdString, CombineMode *combineMode);
|
||||||
void makeXmirror(const std::vector<QVector3D> &sourceVertices, const std::vector<std::vector<size_t>> &sourceFaces,
|
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);
|
std::vector<QVector3D> *destVertices, std::vector<std::vector<size_t>> *destFaces);
|
||||||
|
|
|
@ -6,6 +6,11 @@
|
||||||
namespace nodemesh
|
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 Modifier::addNode(const QVector3D &position, float radius, const std::vector<QVector2D> &cutTemplate, float cutRotation)
|
||||||
{
|
{
|
||||||
size_t nodeIndex = m_nodes.size();
|
size_t nodeIndex = m_nodes.size();
|
||||||
|
@ -100,6 +105,8 @@ void Modifier::roundEnd()
|
||||||
|
|
||||||
void Modifier::finalize()
|
void Modifier::finalize()
|
||||||
{
|
{
|
||||||
|
if (!m_intermediateAdditionEnabled)
|
||||||
|
return;
|
||||||
auto oldEdges = m_edges;
|
auto oldEdges = m_edges;
|
||||||
m_edges.clear();
|
m_edges.clear();
|
||||||
for (const auto &edge: oldEdges) {
|
for (const auto &edge: oldEdges) {
|
||||||
|
|
|
@ -31,6 +31,7 @@ public:
|
||||||
size_t addEdge(size_t firstNodeIndex, size_t secondNodeIndex);
|
size_t addEdge(size_t firstNodeIndex, size_t secondNodeIndex);
|
||||||
void subdivide();
|
void subdivide();
|
||||||
void roundEnd();
|
void roundEnd();
|
||||||
|
void enableIntermediateAddition();
|
||||||
const std::vector<Node> &nodes();
|
const std::vector<Node> &nodes();
|
||||||
const std::vector<Edge> &edges();
|
const std::vector<Edge> &edges();
|
||||||
void finalize();
|
void finalize();
|
||||||
|
@ -39,6 +40,7 @@ private:
|
||||||
|
|
||||||
std::vector<Node> m_nodes;
|
std::vector<Node> m_nodes;
|
||||||
std::vector<Edge> m_edges;
|
std::vector<Edge> m_edges;
|
||||||
|
bool m_intermediateAdditionEnabled = false;
|
||||||
|
|
||||||
void createIntermediateNode(const Node &firstNode, const Node &secondNode, float factor, Node *resultNode);
|
void createIntermediateNode(const Node &firstNode, const Node &secondNode, float factor, Node *resultNode);
|
||||||
float averageCutTemplateEdgeLength(const std::vector<QVector2D> &cutTemplate);
|
float averageCutTemplateEdgeLength(const std::vector<QVector2D> &cutTemplate);
|
||||||
|
|
Loading…
Reference in New Issue