From 0ae64265879ac7e4c0670650023c805071b55f78 Mon Sep 17 00:00:00 2001 From: huxingyi Date: Sun, 18 Oct 2020 20:01:40 +0930 Subject: [PATCH] Add deform parameter: deformUnified If deformUnified got checked, all the vertices will be unified to the same thickness or width. --- dust3d.pro | 1 + resources/model-bicycle.ds3 | 1016 +++++++++++++++++------------------ resources/model-dog.ds3 | 538 +++++++++---------- resources/model-giraffe.ds3 | 512 +++++++++--------- src/document.cpp | 20 + src/document.h | 2 + src/meshgenerator.cpp | 3 + src/partwidget.cpp | 18 +- src/partwidget.h | 1 + src/skeletondocument.h | 4 +- src/strokemeshbuilder.cpp | 17 +- src/strokemeshbuilder.h | 2 + 12 files changed, 1097 insertions(+), 1037 deletions(-) diff --git a/dust3d.pro b/dust3d.pro index a0b23060..6d8a0e7e 100644 --- a/dust3d.pro +++ b/dust3d.pro @@ -124,6 +124,7 @@ unix:!macx { } win32 { + QMAKE_CXXFLAGS += /MP QMAKE_CXXFLAGS += /O2 QMAKE_CXXFLAGS += /bigobj } diff --git a/resources/model-bicycle.ds3 b/resources/model-bicycle.ds3 index 299f083f..a90194fd 100644 --- a/resources/model-bicycle.ds3 +++ b/resources/model-bicycle.ds3 @@ -1,524 +1,524 @@ DUST3D 1.0 xml 0000000193 - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/model-dog.ds3 b/resources/model-dog.ds3 index e812b46b..564f9307 100644 --- a/resources/model-dog.ds3 +++ b/resources/model-dog.ds3 @@ -1,287 +1,287 @@ DUST3D 1.0 xml 0000000194 - - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - + + + + - - - - + + + + - - - - + + + + diff --git a/resources/model-giraffe.ds3 b/resources/model-giraffe.ds3 index 24bfe106..8ecf59be 100644 --- a/resources/model-giraffe.ds3 +++ b/resources/model-giraffe.ds3 @@ -1,273 +1,273 @@ DUST3D 1.0 xml 0000000494 - - - - - + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - + diff --git a/src/document.cpp b/src/document.cpp index 32c1c62b..7ea45143 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -1181,6 +1181,8 @@ void Document::toSnapshot(Snapshot *snapshot, const std::set &limitNodeId part["deformThickness"] = QString::number(partIt.second.deformThickness); if (partIt.second.deformWidthAdjusted()) part["deformWidth"] = QString::number(partIt.second.deformWidth); + if (partIt.second.deformUnified) + part["deformUnified"] = "true"; if (!partIt.second.deformMapImageId.isNull()) part["deformMapImageId"] = partIt.second.deformMapImageId.toString(); if (partIt.second.deformMapScaleAdjusted()) @@ -1609,6 +1611,9 @@ void Document::addFromSnapshot(const Snapshot &snapshot, enum SnapshotSource sou const auto &deformWidthIt = partKv.second.find("deformWidth"); if (deformWidthIt != partKv.second.end()) part.setDeformWidth(deformWidthIt->second.toFloat()); + const auto &deformUnifiedIt = partKv.second.find("deformUnified"); + if (deformUnifiedIt != partKv.second.end()) + part.deformUnified = isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "deformUnified")); const auto &deformMapImageIdIt = partKv.second.find("deformMapImageId"); if (deformMapImageIdIt != partKv.second.end()) part.deformMapImageId = QUuid(deformMapImageIdIt->second); @@ -2977,6 +2982,21 @@ void Document::setPartDeformWidth(QUuid partId, float width) emit skeletonChanged(); } +void Document::setPartDeformUnified(QUuid partId, bool unified) +{ + auto part = partMap.find(partId); + if (part == partMap.end()) { + qDebug() << "Part not found:" << partId; + return; + } + if (part->second.deformUnified == unified) + return; + part->second.deformUnified = unified; + part->second.dirty = true; + emit partDeformUnifyStateChanged(partId); + emit skeletonChanged(); +} + void Document::setPartDeformMapImageId(QUuid partId, QUuid imageId) { auto part = partMap.find(partId); diff --git a/src/document.h b/src/document.h index 30dd674d..4f8cb98c 100644 --- a/src/document.h +++ b/src/document.h @@ -458,6 +458,7 @@ signals: void partBaseChanged(QUuid partId); void partDeformThicknessChanged(QUuid partId); void partDeformWidthChanged(QUuid partId); + void partDeformUnifyStateChanged(QUuid partId); void partDeformMapImageIdChanged(QUuid partId); void partDeformMapScaleChanged(QUuid partId); void partRoundStateChanged(QUuid partId); @@ -665,6 +666,7 @@ public slots: void setPartBase(QUuid partId, PartBase base); void setPartDeformThickness(QUuid partId, float thickness); void setPartDeformWidth(QUuid partId, float width); + void setPartDeformUnified(QUuid partId, bool unified); void setPartDeformMapImageId(QUuid partId, QUuid imageId); void setPartDeformMapScale(QUuid partId, float scale); void setPartRoundState(QUuid partId, bool rounded); diff --git a/src/meshgenerator.cpp b/src/meshgenerator.cpp index 82cf55bf..befbc310 100644 --- a/src/meshgenerator.cpp +++ b/src/meshgenerator.cpp @@ -389,6 +389,8 @@ MeshCombiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdString, deformWidth = widthString.toFloat(); } + bool deformUnified = isTrueValueString(valueOfKeyInMapOrEmpty(part, "deformUnified")); + QImage deformImageStruct; const QImage *deformImage = nullptr; QString deformMapImageIdString = valueOfKeyInMapOrEmpty(part, "deformMapImageId"); @@ -636,6 +638,7 @@ MeshCombiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdString, strokeMeshBuilder->setDeformThickness(deformThickness); strokeMeshBuilder->setDeformWidth(deformWidth); strokeMeshBuilder->setDeformMapScale(deformMapScale); + strokeMeshBuilder->setDeformUnified(deformUnified); strokeMeshBuilder->setHollowThickness(hollowThickness); if (nullptr != deformImage) strokeMeshBuilder->setDeformMapImage(deformImage); diff --git a/src/partwidget.cpp b/src/partwidget.cpp index c2214f61..f19902fe 100644 --- a/src/partwidget.cpp +++ b/src/partwidget.cpp @@ -167,6 +167,7 @@ PartWidget::PartWidget(const Document *document, QUuid partId) : connect(this, &PartWidget::setPartXmirrorState, m_document, &Document::setPartXmirrorState); connect(this, &PartWidget::setPartDeformThickness, m_document, &Document::setPartDeformThickness); connect(this, &PartWidget::setPartDeformWidth, m_document, &Document::setPartDeformWidth); + connect(this, &PartWidget::setPartDeformUnified, m_document, &Document::setPartDeformUnified); connect(this, &PartWidget::setPartDeformMapImageId, m_document, &Document::setPartDeformMapImageId); connect(this, &PartWidget::setPartDeformMapScale, m_document, &Document::setPartDeformMapScale); connect(this, &PartWidget::setPartRoundState, m_document, &Document::setPartRoundState); @@ -765,9 +766,24 @@ void PartWidget::showDeformSettingPopup(const QPoint &pos) thicknessLayout->addWidget(thicknessWidget); widthLayout->addWidget(widthEraser); widthLayout->addWidget(widthWidget); + + QCheckBox *deformUnifyStateBox = new QCheckBox(); + Theme::initCheckbox(deformUnifyStateBox); + deformUnifyStateBox->setText(tr("Unified")); + deformUnifyStateBox->setChecked(part->deformUnified); + + connect(deformUnifyStateBox, &QCheckBox::stateChanged, this, [=]() { + emit setPartDeformUnified(m_partId, deformUnifyStateBox->isChecked()); + emit groupOperationAdded(); + }); + + QHBoxLayout *deformUnifyLayout = new QHBoxLayout; + deformUnifyLayout->addStretch(); + deformUnifyLayout->addWidget(deformUnifyStateBox); mainLayout->addLayout(thicknessLayout); mainLayout->addLayout(widthLayout); + mainLayout->addLayout(deformUnifyLayout); popup->setLayout(mainLayout); @@ -871,7 +887,7 @@ void PartWidget::updateDeformButton() qDebug() << "Part not found:" << m_partId; return; } - if (part->deformAdjusted() || part->deformMapAdjusted()) + if (part->deformAdjusted() || part->deformMapAdjusted() || part->deformUnified) updateButton(m_deformButton, QChar(fa::handlizardo), true, part->hasDeformFunction()); else updateButton(m_deformButton, QChar(fa::handlizardo), false, part->hasDeformFunction()); diff --git a/src/partwidget.h b/src/partwidget.h index 1d703e24..08631928 100644 --- a/src/partwidget.h +++ b/src/partwidget.h @@ -18,6 +18,7 @@ signals: void setPartZmirrorState(QUuid partId, bool mirrored); void setPartDeformThickness(QUuid partId, float thickness); void setPartDeformWidth(QUuid partId, float width); + void setPartDeformUnified(QUuid partId, bool unified); void setPartDeformMapImageId(QUuid partId, QUuid imageId); void setPartDeformMapScale(QUuid partId, float scale); void setPartRoundState(QUuid partId, bool rounded); diff --git a/src/skeletondocument.h b/src/skeletondocument.h index d4be3b16..96126216 100644 --- a/src/skeletondocument.h +++ b/src/skeletondocument.h @@ -164,6 +164,7 @@ public: PartBase base; float deformThickness; float deformWidth; + bool deformUnified; bool rounded; bool chamfered; QColor color; @@ -197,6 +198,7 @@ public: base(PartBase::Average), deformThickness(1.0), deformWidth(1.0), + deformUnified(false), rounded(false), chamfered(false), color(Preferences::instance().partColor()), @@ -324,7 +326,7 @@ public: } bool deformAdjusted() const { - return deformThicknessAdjusted() || deformWidthAdjusted(); + return deformThicknessAdjusted() || deformWidthAdjusted() || deformUnified; } bool deformMapScaleAdjusted() const { diff --git a/src/strokemeshbuilder.cpp b/src/strokemeshbuilder.cpp index 0b38bb92..0a48a734 100644 --- a/src/strokemeshbuilder.cpp +++ b/src/strokemeshbuilder.cpp @@ -47,6 +47,11 @@ void StrokeMeshBuilder::setDeformWidth(float width) m_deformWidth = width; } +void StrokeMeshBuilder::setDeformUnified(bool unified) +{ + m_deformUnified = unified; +} + void StrokeMeshBuilder::setDeformMapImage(const QImage *image) { m_deformMapImage = image; @@ -665,6 +670,13 @@ QVector3D StrokeMeshBuilder::calculateDeformPosition(const QVector3D &vertexPosi void StrokeMeshBuilder::applyDeform() { + float maxRadius = 0.0; + if (m_deformUnified) { + for (const auto &node: m_nodes) { + if (node.radius > maxRadius) + maxRadius = node.radius; + } + } for (size_t i = 0; i < m_generatedVertices.size(); ++i) { auto &position = m_generatedVertices[i]; const auto &node = m_nodes[m_generatedVerticesSourceNodeIndices[i]]; @@ -682,13 +694,14 @@ void StrokeMeshBuilder::applyDeform() } QVector3D sum; size_t count = 0; + float deformUnifyFactor = m_deformUnified ? maxRadius / node.radius : 1.0; if (!qFuzzyCompare(m_deformThickness, (float)1.0)) { - auto deformedPosition = calculateDeformPosition(position, ray, node.baseNormal, m_deformThickness); + auto deformedPosition = calculateDeformPosition(position, ray, node.baseNormal, m_deformThickness * deformUnifyFactor); sum += deformedPosition; ++count; } if (!qFuzzyCompare(m_deformWidth, (float)1.0)) { - auto deformedPosition = calculateDeformPosition(position, ray, QVector3D::crossProduct(node.baseNormal, cutDirect), m_deformWidth); + auto deformedPosition = calculateDeformPosition(position, ray, QVector3D::crossProduct(node.baseNormal, cutDirect), m_deformWidth * deformUnifyFactor); sum += deformedPosition; ++count; } diff --git a/src/strokemeshbuilder.h b/src/strokemeshbuilder.h index f0545f5e..6dc5a200 100644 --- a/src/strokemeshbuilder.h +++ b/src/strokemeshbuilder.h @@ -47,6 +47,7 @@ public: void setNodeOriginInfo(size_t nodeIndex, int nearOriginNodeIndex, int farOriginNodeIndex); void setDeformThickness(float thickness); void setDeformWidth(float width); + void setDeformUnified(bool unified); void setDeformMapImage(const QImage *image); void setDeformMapScale(float scale); void setHollowThickness(float hollowThickness); @@ -85,6 +86,7 @@ private: const QImage *m_deformMapImage = nullptr; float m_deformMapScale = 0.0f; float m_hollowThickness = 0.0f; + bool m_deformUnified = false; bool m_isRing = false; std::vector m_nodeIndices;