Interpolate cut edges after deforming
parent
3af98c5334
commit
eb478d1b54
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include <QPolygon>
|
||||
#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<QUuid, StrokeMeshBuilder::CutFaceTransform> *m_resultMeshCutFaceTransforms;
|
||||
//std::map<QUuid, StrokeMeshBuilder::CutFaceTransform> *m_resultMeshCutFaceTransforms;
|
||||
std::map<QUuid, std::map<QString, QVector2D>> *m_resultMeshNodesCutFaces;
|
||||
bool m_isMeshGenerationSucceed;
|
||||
int m_batchChangeRefCount;
|
||||
|
@ -824,11 +825,11 @@ private: // need initialize
|
|||
float m_mousePickRadius;
|
||||
bool m_saveNextPaintSnapshot;
|
||||
VoxelGrid<PaintColor> *m_vertexColorVoxelGrid;
|
||||
GeneratedCacheContext *m_generatedCacheContext;
|
||||
private:
|
||||
static unsigned long m_maxSnapshot;
|
||||
std::deque<HistoryItem> m_undoItems;
|
||||
std::deque<HistoryItem> m_redoItems;
|
||||
GeneratedCacheContext m_generatedCacheContext;
|
||||
std::vector<std::pair<QtMsgType, QString>> m_resultRigMessages;
|
||||
QVector3D m_mouseRayNear;
|
||||
QVector3D m_mouseRayFar;
|
||||
|
|
|
@ -39,10 +39,12 @@ void remeshHole(std::vector<QVector3D> &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<typename CGAL::Surface_mesh<typename Kernel::Point_3>::Vertex_index> meshFace;
|
||||
std::vector<size_t> originalIndices;
|
||||
|
|
|
@ -247,6 +247,53 @@ void StrokeMeshBuilder::buildMesh()
|
|||
}
|
||||
}
|
||||
|
||||
void StrokeMeshBuilder::interpolateCutEdges()
|
||||
{
|
||||
std::vector<std::vector<size_t>> interpolatedCuts;
|
||||
|
||||
for (const auto &cut: m_cuts) {
|
||||
double sumOfLegnth = 0;
|
||||
std::vector<double> 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<size_t> 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;
|
||||
}
|
||||
|
|
|
@ -118,6 +118,7 @@ private:
|
|||
std::vector<size_t> edgeloopFlipped(const std::vector<size_t> &edgeLoop);
|
||||
void reviseNodeBaseNormal(Node &node);
|
||||
void applyDeform();
|
||||
void interpolateCutEdges();
|
||||
void stitchCuts();
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue