diff --git a/languages/dust3d_zh_CN.ts b/languages/dust3d_zh_CN.ts index 24b22e63..e26a90e5 100644 --- a/languages/dust3d_zh_CN.ts +++ b/languages/dust3d_zh_CN.ts @@ -768,6 +768,10 @@ Tips: Offset 偏移 + + Iteration + 迭代 + PartWidget diff --git a/src/document.cpp b/src/document.cpp index de3830b3..338c404d 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -22,7 +22,8 @@ #include "contourtopartconverter.h" unsigned long Document::m_maxSnapshot = 1000; -const float Component::defaultStiffness = 0.5f; +const float Component::defaultClothStiffness = 0.5f; +const size_t Component::defaultClothIteration = 350; Document::Document() : SkeletonDocument(), @@ -1209,6 +1210,8 @@ void Document::toSnapshot(Snapshot *snapshot, const std::set &limitNodeId component["layer"] = ComponentLayerToString(componentIt.second.layer); if (componentIt.second.clothStiffnessAdjusted()) component["clothStiffness"] = QString::number(componentIt.second.clothStiffness); + if (componentIt.second.clothIterationAdjusted()) + component["clothIteration"] = QString::number(componentIt.second.clothIteration); if (componentIt.second.clothForceAdjusted()) component["clothForce"] = ClothForceToString(componentIt.second.clothForce); if (componentIt.second.clothOffsetAdjusted()) @@ -1724,6 +1727,9 @@ void Document::addFromSnapshot(const Snapshot &snapshot, bool fromPaste) auto findClothStiffness = componentKv.second.find("clothStiffness"); if (findClothStiffness != componentKv.second.end()) component.clothStiffness = findClothStiffness->second.toFloat(); + auto findClothIteration = componentKv.second.find("clothIteration"); + if (findClothIteration != componentKv.second.end()) + component.clothIteration = findClothIteration->second.toUInt(); auto findClothForce = componentKv.second.find("clothForce"); if (findClothForce != componentKv.second.end()) component.clothForce = ClothForceFromString(valueOfKeyInMapOrEmpty(componentKv.second, "clothForce").toUtf8().constData()); @@ -2566,6 +2572,20 @@ void Document::setComponentClothStiffness(QUuid componentId, float stiffness) emit skeletonChanged(); } +void Document::setComponentClothIteration(QUuid componentId, size_t iteration) +{ + Component *component = (Component *)findComponent(componentId); + if (nullptr == component) + return; + if (component->clothIteration == iteration) + return; + + component->clothIteration = iteration; + component->dirty = true; + emit componentClothIterationChanged(componentId); + emit skeletonChanged(); +} + void Document::setComponentClothForce(QUuid componentId, ClothForce force) { Component *component = (Component *)findComponent(componentId); diff --git a/src/document.h b/src/document.h index f05f41e3..2552948f 100644 --- a/src/document.h +++ b/src/document.h @@ -48,7 +48,8 @@ public: class Component { public: - static const float defaultStiffness; + static const float defaultClothStiffness; + static const size_t defaultClothIteration; Component() { } @@ -72,9 +73,10 @@ public: float smoothSeam = 0.0; PolyCount polyCount = PolyCount::Original; ComponentLayer layer = ComponentLayer::Body; - float clothStiffness = defaultStiffness; + float clothStiffness = defaultClothStiffness; ClothForce clothForce = ClothForce::Gravitational; float clothOffset = 0.0f; + size_t clothIteration = defaultClothIteration; std::vector childrenIds; QString linkData() const { @@ -196,7 +198,11 @@ public: } bool clothStiffnessAdjusted() const { - return fabs(clothStiffness - Component::defaultStiffness) >= 0.01; + return fabs(clothStiffness - Component::defaultClothStiffness) >= 0.01; + } + bool clothIterationAdjusted() const + { + return clothIteration != defaultClothIteration; } bool clothForceAdjusted() const { @@ -418,6 +424,7 @@ signals: void componentPolyCountChanged(QUuid componentId); void componentLayerChanged(QUuid componentId); void componentClothStiffnessChanged(QUuid componentId); + void componentClothIterationChanged(QUuid componentId); void componentClothForceChanged(QUuid componentId); void componentClothOffsetChanged(QUuid componentId); void nodeRemoved(QUuid nodeId); @@ -679,6 +686,7 @@ public slots: void setComponentPolyCount(QUuid componentId, PolyCount count); void setComponentLayer(QUuid componentId, ComponentLayer layer); void setComponentClothStiffness(QUuid componentId, float stiffness); + void setComponentClothIteration(QUuid componentId, size_t iteration); void setComponentClothForce(QUuid componentId, ClothForce force); void setComponentClothOffset(QUuid componentId, float offset); void hideOtherComponents(QUuid componentId); diff --git a/src/documentwindow.cpp b/src/documentwindow.cpp index 7c1c570c..fc7ca43a 100644 --- a/src/documentwindow.cpp +++ b/src/documentwindow.cpp @@ -1044,6 +1044,7 @@ DocumentWindow::DocumentWindow() : connect(partTreeWidget, &PartTreeWidget::setPartColorState, m_document, &Document::setPartColorState); connect(partTreeWidget, &PartTreeWidget::setComponentCombineMode, m_document, &Document::setComponentCombineMode); connect(partTreeWidget, &PartTreeWidget::setComponentClothStiffness, m_document, &Document::setComponentClothStiffness); + connect(partTreeWidget, &PartTreeWidget::setComponentClothIteration, m_document, &Document::setComponentClothIteration); connect(partTreeWidget, &PartTreeWidget::setComponentClothForce, m_document, &Document::setComponentClothForce); connect(partTreeWidget, &PartTreeWidget::setComponentClothOffset, m_document, &Document::setComponentClothOffset); connect(partTreeWidget, &PartTreeWidget::setPartTarget, m_document, &Document::setPartTarget); diff --git a/src/meshgenerator.cpp b/src/meshgenerator.cpp index 827c2911..694cee63 100644 --- a/src/meshgenerator.cpp +++ b/src/meshgenerator.cpp @@ -919,13 +919,23 @@ ComponentLayer MeshGenerator::componentLayer(const std::map *c float MeshGenerator::componentClothStiffness(const std::map *component) { if (nullptr == component) - return Component::defaultStiffness; + return Component::defaultClothStiffness; auto findClothStiffness = component->find("clothStiffness"); if (findClothStiffness == component->end()) - return Component::defaultStiffness; + return Component::defaultClothStiffness; return findClothStiffness->second.toFloat(); } +size_t MeshGenerator::componentClothIteration(const std::map *component) +{ + if (nullptr == component) + return Component::defaultClothIteration; + auto findClothIteration = component->find("clothIteration"); + if (findClothIteration == component->end()) + return Component::defaultClothIteration; + return findClothIteration->second.toUInt(); +} + ClothForce MeshGenerator::componentClothForce(const std::map *component) { if (nullptr == component) @@ -1723,6 +1733,7 @@ void MeshGenerator::collectClothComponent(const QString &componentIdString) clothMesh.clothForce = componentClothForce(component); clothMesh.clothOffset = componentClothOffset(component); clothMesh.clothStiffness = componentClothStiffness(component); + clothMesh.clothIteration = componentClothIteration(component); clothMesh.outcomeNodeVertices = &componentCache.outcomeNodeVertices; m_outcome->nodes.insert(m_outcome->nodes.end(), componentCache.outcomeNodes.begin(), componentCache.outcomeNodes.end()); } diff --git a/src/meshgenerator.h b/src/meshgenerator.h index 0e0bc9b8..1ddb3195 100644 --- a/src/meshgenerator.h +++ b/src/meshgenerator.h @@ -133,6 +133,7 @@ private: QString componentColorName(const std::map *component); ComponentLayer componentLayer(const std::map *component); float componentClothStiffness(const std::map *component); + size_t componentClothIteration(const std::map *component); ClothForce componentClothForce(const std::map *component); float componentClothOffset(const std::map *component); void collectUncombinedComponent(const QString &componentIdString); diff --git a/src/parttreewidget.cpp b/src/parttreewidget.cpp index 85ffa8ba..510f9d4f 100644 --- a/src/parttreewidget.cpp +++ b/src/parttreewidget.cpp @@ -15,6 +15,7 @@ #include "partwidget.h" #include "skeletongraphicswidget.h" #include "floatnumberwidget.h" +#include "intnumberwidget.h" PartTreeWidget::PartTreeWidget(const Document *document, QWidget *parent) : QTreeWidget(parent), @@ -285,7 +286,7 @@ void PartTreeWidget::showClothSettingMenu(const QPoint &pos, const QUuid &compon Theme::initAwesomeToolButton(clothStiffnessEraser); connect(clothStiffnessEraser, &QPushButton::clicked, [=]() { - clothStiffnessWidget->setValue(Component::defaultStiffness); + clothStiffnessWidget->setValue(Component::defaultClothStiffness); emit groupOperationAdded(); }); @@ -293,6 +294,28 @@ void PartTreeWidget::showClothSettingMenu(const QPoint &pos, const QUuid &compon clothStiffnessLayout->addWidget(clothStiffnessEraser); clothStiffnessLayout->addWidget(clothStiffnessWidget); + IntNumberWidget *clothIterationWidget = new IntNumberWidget; + clothIterationWidget->setItemName(tr("Iteration")); + clothIterationWidget->setRange(0, 1000); + clothIterationWidget->setValue(component->clothIteration); + + connect(clothIterationWidget, &IntNumberWidget::valueChanged, [=](int value) { + //emit setComponentClothIteration(componentId, value); + //emit groupOperationAdded(); + }); + + QPushButton *clothIterationEraser = new QPushButton(QChar(fa::eraser)); + Theme::initAwesomeToolButton(clothIterationEraser); + + connect(clothIterationEraser, &QPushButton::clicked, [=]() { + clothIterationWidget->setValue(Component::defaultClothIteration); + emit groupOperationAdded(); + }); + + QHBoxLayout *clothIterationLayout = new QHBoxLayout; + clothIterationLayout->addWidget(clothIterationEraser); + clothIterationLayout->addWidget(clothIterationWidget); + FloatNumberWidget *clothOffsetWidget = new FloatNumberWidget; clothOffsetWidget->setItemName(tr("Offset")); clothOffsetWidget->setRange(0.0f, 1.0f); @@ -333,6 +356,7 @@ void PartTreeWidget::showClothSettingMenu(const QPoint &pos, const QUuid &compon QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addLayout(clothStiffnessLayout); + //mainLayout->addLayout(clothIterationLayout); mainLayout->addLayout(clothOffsetLayout); mainLayout->addLayout(clothForceLayout); diff --git a/src/parttreewidget.h b/src/parttreewidget.h index bd156f42..555dcbce 100644 --- a/src/parttreewidget.h +++ b/src/parttreewidget.h @@ -43,6 +43,7 @@ signals: void setPartColorState(QUuid partId, bool hasColor, QColor color); void setComponentCombineMode(QUuid componentId, CombineMode combineMode); void setComponentClothStiffness(QUuid componentId, float clothStiffness); + void setComponentClothIteration(QUuid componentId, size_t iteration); void setComponentClothForce(QUuid componentId, ClothForce force); void setComponentClothOffset(QUuid componentId, float offset); void hideDescendantComponents(QUuid componentId); diff --git a/src/simulateclothmeshes.cpp b/src/simulateclothmeshes.cpp index 09a3835b..c672e5c6 100644 --- a/src/simulateclothmeshes.cpp +++ b/src/simulateclothmeshes.cpp @@ -58,7 +58,7 @@ public: externalForces); clothSimulator.setStiffness(clothMesh->clothStiffness); clothSimulator.create(); - for (size_t i = 0; i < 350; ++i) + for (size_t i = 0; i < clothMesh->clothIteration; ++i) clothSimulator.step(); clothSimulator.getCurrentVertices(&filteredClothVertices); for (size_t i = 0; i < filteredClothVertices.size(); ++i) { diff --git a/src/simulateclothmeshes.h b/src/simulateclothmeshes.h index 2a9eb9c2..e3ca98ad 100644 --- a/src/simulateclothmeshes.h +++ b/src/simulateclothmeshes.h @@ -14,6 +14,7 @@ struct ClothMesh ClothForce clothForce; float clothOffset; float clothStiffness; + size_t clothIteration; }; void simulateClothMeshes(std::vector *clothMeshes,