From eb478d1b54f80c05c2935708af09f042c287cfcd Mon Sep 17 00:00:00 2001 From: huxingyi Date: Mon, 19 Oct 2020 00:04:43 +0930 Subject: [PATCH] Interpolate cut edges after deforming --- src/document.cpp | 16 ++++++++----- src/document.h | 7 +++--- src/remeshhole.cpp | 6 +++-- src/strokemeshbuilder.cpp | 48 +++++++++++++++++++++++++++++++++++++++ src/strokemeshbuilder.h | 1 + 5 files changed, 67 insertions(+), 11 deletions(-) diff --git a/src/document.cpp b/src/document.cpp index 7ea45143..785cb94a 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -19,6 +19,7 @@ #include "scriptrunner.h" #include "imageforever.h" #include "contourtopartconverter.h" +#include "meshgenerator.h" unsigned long Document::m_maxSnapshot = 1000; const float Component::defaultClothStiffness = 0.5f; @@ -46,7 +47,7 @@ Document::Document() : m_meshGenerator(nullptr), m_resultMesh(nullptr), m_paintedMesh(nullptr), - m_resultMeshCutFaceTransforms(nullptr), + //m_resultMeshCutFaceTransforms(nullptr), m_resultMeshNodesCutFaces(nullptr), m_isMeshGenerationSucceed(true), m_batchChangeRefCount(0), @@ -79,7 +80,8 @@ Document::Document() : m_paintMode(PaintMode::None), m_mousePickRadius(0.05), m_saveNextPaintSnapshot(false), - m_vertexColorVoxelGrid(nullptr) + m_vertexColorVoxelGrid(nullptr), + m_generatedCacheContext(nullptr) { connect(&Preferences::instance(), &Preferences::partColorChanged, this, &Document::applyPreferencePartColorChange); connect(&Preferences::instance(), &Preferences::flatShadingChanged, this, &Document::applyPreferenceFlatShadingChange); @@ -106,7 +108,7 @@ Document::~Document() { delete m_resultMesh; delete m_paintedMesh; - delete m_resultMeshCutFaceTransforms; + //delete m_resultMeshCutFaceTransforms; delete m_resultMeshNodesCutFaces; delete m_postProcessedOutcome; delete textureGuideImage; @@ -1970,8 +1972,8 @@ void Document::meshReady() delete m_resultMesh; m_resultMesh = resultMesh; - delete m_resultMeshCutFaceTransforms; - m_resultMeshCutFaceTransforms = m_meshGenerator->takeCutFaceTransforms(); + //delete m_resultMeshCutFaceTransforms; + //m_resultMeshCutFaceTransforms = m_meshGenerator->takeCutFaceTransforms(); delete m_resultMeshNodesCutFaces; m_resultMeshNodesCutFaces = m_meshGenerator->takeNodesCutFaces(); @@ -2093,7 +2095,9 @@ void Document::generateMesh() m_meshGenerator = new MeshGenerator(snapshot); m_meshGenerator->setId(m_nextMeshGenerationId++); m_meshGenerator->setDefaultPartColor(Preferences::instance().partColor()); - m_meshGenerator->setGeneratedCacheContext(&m_generatedCacheContext); + if (nullptr == m_generatedCacheContext) + m_generatedCacheContext = new GeneratedCacheContext; + m_meshGenerator->setGeneratedCacheContext(m_generatedCacheContext); if (!m_smoothNormal) { m_meshGenerator->setSmoothShadingThresholdAngleDegrees(0); } diff --git a/src/document.h b/src/document.h index 4f8cb98c..3a57d530 100644 --- a/src/document.h +++ b/src/document.h @@ -12,7 +12,6 @@ #include #include "snapshot.h" #include "model.h" -#include "meshgenerator.h" #include "theme.h" #include "texturegenerator.h" #include "meshresultpostprocessor.h" @@ -37,6 +36,8 @@ class MaterialPreviewsGenerator; class MotionsGenerator; class ScriptRunner; +class MeshGenerator; +class GeneratedCacheContext; class HistoryItem { @@ -787,7 +788,7 @@ private: // need initialize MeshGenerator *m_meshGenerator; Model *m_resultMesh; Model *m_paintedMesh; - std::map *m_resultMeshCutFaceTransforms; + //std::map *m_resultMeshCutFaceTransforms; std::map> *m_resultMeshNodesCutFaces; bool m_isMeshGenerationSucceed; int m_batchChangeRefCount; @@ -824,11 +825,11 @@ private: // need initialize float m_mousePickRadius; bool m_saveNextPaintSnapshot; VoxelGrid *m_vertexColorVoxelGrid; + GeneratedCacheContext *m_generatedCacheContext; private: static unsigned long m_maxSnapshot; std::deque m_undoItems; std::deque m_redoItems; - GeneratedCacheContext m_generatedCacheContext; std::vector> m_resultRigMessages; QVector3D m_mouseRayNear; QVector3D m_mouseRayFar; diff --git a/src/remeshhole.cpp b/src/remeshhole.cpp index ea943455..c188c17b 100644 --- a/src/remeshhole.cpp +++ b/src/remeshhole.cpp @@ -39,10 +39,12 @@ void remeshHole(std::vector &vertices, Mesh mesh; double targetEdgeLength = 0; - for (size_t i = 1; i < hole.size(); ++i) { - targetEdgeLength += (vertices[hole[i - 1]] - vertices[hole[i]]).length(); + for (size_t i = 0; i < hole.size(); ++i) { + size_t j = (i + 1) % hole.size(); + targetEdgeLength += (vertices[hole[i]] - vertices[hole[j]]).length(); } targetEdgeLength /= hole.size(); + targetEdgeLength *= 1.2; std::vector::Vertex_index> meshFace; std::vector originalIndices; diff --git a/src/strokemeshbuilder.cpp b/src/strokemeshbuilder.cpp index 2a3846d8..735c0415 100644 --- a/src/strokemeshbuilder.cpp +++ b/src/strokemeshbuilder.cpp @@ -247,6 +247,53 @@ void StrokeMeshBuilder::buildMesh() } } +void StrokeMeshBuilder::interpolateCutEdges() +{ + std::vector> interpolatedCuts; + + for (const auto &cut: m_cuts) { + double sumOfLegnth = 0; + std::vector edgeLengths; + edgeLengths.reserve(cut.size()); + for (size_t i = 0; i < cut.size(); ++i) { + size_t j = (i + 1) % cut.size(); + double length = (m_generatedVertices[cut[i]] - m_generatedVertices[cut[j]]).length(); + edgeLengths.push_back(length); + sumOfLegnth += length; + } + double targetLength = 1.2 * sumOfLegnth / cut.size(); + std::vector newCut; + for (size_t index = 0; index < cut.size(); ++index) { + size_t nextIndex = (index + 1) % cut.size(); + newCut.push_back(cut[index]); + const auto &oldEdgeLength = edgeLengths[index]; + if (targetLength >= oldEdgeLength) + continue; + size_t newInsertNum = oldEdgeLength / targetLength; + qDebug() << "oldEdgeLength:" << oldEdgeLength << "targetLength:" << targetLength << "newInsertNum:" << newInsertNum; + if (newInsertNum < 1) + newInsertNum = 1; + if (newInsertNum > 100) + continue; + float stepFactor = 1.0 / (newInsertNum + 1); + float factor = stepFactor; + for (size_t i = 0; i < newInsertNum && factor < 1.0; factor += stepFactor, ++i) { + float firstFactor = 1.0 - factor; + auto newPosition = m_generatedVertices[cut[index]] * firstFactor + m_generatedVertices[cut[nextIndex]] * factor; + newCut.push_back(m_generatedVertices.size()); + m_generatedVertices.push_back(newPosition); + const auto &oldIndex = cut[index]; + m_generatedVerticesCutDirects.push_back(m_generatedVerticesCutDirects[oldIndex]); + m_generatedVerticesSourceNodeIndices.push_back(m_generatedVerticesSourceNodeIndices[oldIndex]); + m_generatedVerticesInfos.push_back(m_generatedVerticesInfos[oldIndex]); + } + } + interpolatedCuts.push_back(newCut); + } + + m_cuts = interpolatedCuts; +} + void StrokeMeshBuilder::stitchCuts() { for (size_t i = m_isRing ? 0 : 1; i < m_nodeIndices.size(); ++i) { @@ -744,6 +791,7 @@ bool StrokeMeshBuilder::build() buildMesh(); applyDeform(); + interpolateCutEdges(); stitchCuts(); return true; } diff --git a/src/strokemeshbuilder.h b/src/strokemeshbuilder.h index 56c98483..b8ad168d 100644 --- a/src/strokemeshbuilder.h +++ b/src/strokemeshbuilder.h @@ -118,6 +118,7 @@ private: std::vector edgeloopFlipped(const std::vector &edgeLoop); void reviseNodeBaseNormal(Node &node); void applyDeform(); + void interpolateCutEdges(); void stitchCuts(); };