diff --git a/src/document.cpp b/src/document.cpp index 001f6da3..c1b41109 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -35,6 +35,7 @@ Document::Document() : m_isResultMeshObsolete(false), m_meshGenerator(nullptr), m_resultMesh(nullptr), + m_isMeshGenerationSucceed(true), m_batchChangeRefCount(0), m_currentOutcome(nullptr), m_isTextureObsolete(false), @@ -1355,6 +1356,11 @@ MeshLoader *Document::takeResultMesh() return resultMesh; } +bool Document::isMeshGenerationSucceed() +{ + return m_isMeshGenerationSucceed; +} + MeshLoader *Document::takeResultTextureMesh() { if (nullptr == m_resultTextureMesh) @@ -1375,6 +1381,7 @@ void Document::meshReady() { MeshLoader *resultMesh = m_meshGenerator->takeResultMesh(); Outcome *outcome = m_meshGenerator->takeOutcome(); + bool isSucceed = m_meshGenerator->isSucceed(); for (auto &partId: m_meshGenerator->generatedPreviewPartIds()) { auto part = partMap.find(partId); @@ -1388,6 +1395,8 @@ void Document::meshReady() delete m_resultMesh; m_resultMesh = resultMesh; + m_isMeshGenerationSucceed = isSucceed; + delete m_currentOutcome; m_currentOutcome = outcome; diff --git a/src/document.h b/src/document.h index 3d557a97..c79e3519 100644 --- a/src/document.h +++ b/src/document.h @@ -491,6 +491,7 @@ public: const Pose *findPose(QUuid poseId) const; const Motion *findMotion(QUuid motionId) const; MeshLoader *takeResultMesh(); + bool isMeshGenerationSucceed(); MeshLoader *takeResultTextureMesh(); MeshLoader *takeResultRigWeightMesh(); const std::vector *resultRigBones() const; @@ -630,6 +631,7 @@ private: // need initialize bool m_isResultMeshObsolete; MeshGenerator *m_meshGenerator; MeshLoader *m_resultMesh; + bool m_isMeshGenerationSucceed; int m_batchChangeRefCount; Outcome *m_currentOutcome; bool m_isTextureObsolete; diff --git a/src/documentwindow.cpp b/src/documentwindow.cpp index 245d8933..f17e8691 100644 --- a/src/documentwindow.cpp +++ b/src/documentwindow.cpp @@ -104,7 +104,8 @@ DocumentWindow::DocumentWindow() : m_firstShow(true), m_documentSaved(true), m_exportPreviewWidget(nullptr), - m_advanceSettingWidget(nullptr) + m_advanceSettingWidget(nullptr), + m_isLastMeshGenerationSucceed(true) { if (!g_logBrowser) { g_logBrowser = new LogBrowser; @@ -120,47 +121,71 @@ DocumentWindow::DocumentWindow() : toolButtonLayout->setContentsMargins(5, 10, 4, 0); QPushButton *addButton = new QPushButton(QChar(fa::plus)); + addButton->setToolTip(tr("Add node to canvas")); Theme::initAwesomeButton(addButton); QPushButton *selectButton = new QPushButton(QChar(fa::mousepointer)); + selectButton->setToolTip(tr("Select node on canvas")); Theme::initAwesomeButton(selectButton); QPushButton *dragButton = new QPushButton(QChar(fa::handrocko)); + dragButton->setToolTip(tr("Enter drag mode")); Theme::initAwesomeButton(dragButton); QPushButton *zoomInButton = new QPushButton(QChar(fa::searchplus)); + zoomInButton->setToolTip(tr("Enter zoom in mode")); Theme::initAwesomeButton(zoomInButton); QPushButton *zoomOutButton = new QPushButton(QChar(fa::searchminus)); + zoomOutButton->setToolTip(tr("Enter zoom out mode")); Theme::initAwesomeButton(zoomOutButton); m_xlockButton = new QPushButton(QChar('X')); + m_xlockButton->setToolTip(tr("X axis locker")); initLockButton(m_xlockButton); updateXlockButtonState(); m_ylockButton = new QPushButton(QChar('Y')); + m_ylockButton->setToolTip(tr("Y axis locker")); initLockButton(m_ylockButton); updateYlockButtonState(); m_zlockButton = new QPushButton(QChar('Z')); + m_zlockButton->setToolTip(tr("Z axis locker")); initLockButton(m_zlockButton); updateZlockButtonState(); m_radiusLockButton = new QPushButton(QChar(fa::bullseye)); + m_radiusLockButton->setToolTip(tr("Node radius locker")); Theme::initAwesomeButton(m_radiusLockButton); updateRadiusLockButtonState(); QPushButton *rotateCounterclockwiseButton = new QPushButton(QChar(fa::rotateleft)); + rotateCounterclockwiseButton->setToolTip(tr("Rotate whole model (CCW)")); Theme::initAwesomeButton(rotateCounterclockwiseButton); QPushButton *rotateClockwiseButton = new QPushButton(QChar(fa::rotateright)); + rotateClockwiseButton->setToolTip(tr("Rotate whole model")); Theme::initAwesomeButton(rotateClockwiseButton); + auto updateRegenerateIconAndTips = [&](SpinnableAwesomeButton *regenerateButton, bool isSucceed, bool forceUpdate=false) { + if (!forceUpdate) { + if (m_isLastMeshGenerationSucceed == isSucceed) + return; + } + m_isLastMeshGenerationSucceed = isSucceed; + regenerateButton->setToolTip(m_isLastMeshGenerationSucceed ? tr("Regenerate") : tr("Mesh generation failed, please undo or adjust recent changed nodes\nTips:\n - Don't let generated mesh self-intersect\n - Make multiple parts instead of one single part for whole model")); + regenerateButton->setAwesomeIcon(m_isLastMeshGenerationSucceed ? QChar(fa::recycle) : QChar(fa::warning)); + }; + SpinnableAwesomeButton *regenerateButton = new SpinnableAwesomeButton(); - regenerateButton->setAwesomeIcon(QChar(fa::recycle)); + updateRegenerateIconAndTips(regenerateButton, m_isLastMeshGenerationSucceed, true); connect(m_document, &Document::meshGenerating, this, [=]() { regenerateButton->showSpinner(true); }); + connect(m_document, &Document::resultMeshChanged, this, [=]() { + updateRegenerateIconAndTips(regenerateButton, m_document->isMeshGenerationSucceed()); + }); connect(m_document, &Document::postProcessing, this, [=]() { regenerateButton->showSpinner(true); }); diff --git a/src/documentwindow.h b/src/documentwindow.h index 8b0ddc42..13e73771 100644 --- a/src/documentwindow.h +++ b/src/documentwindow.h @@ -72,6 +72,7 @@ private: ExportPreviewWidget *m_exportPreviewWidget; AdvanceSettingWidget *m_advanceSettingWidget; std::vector m_dialogs; + bool m_isLastMeshGenerationSucceed; private: QString m_currentFilename; diff --git a/src/main.cpp b/src/main.cpp index 4efe23eb..ba02902f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -25,8 +25,8 @@ int main(int argc, char ** argv) darkPalette.setColor(QPalette::WindowText, Theme::white); darkPalette.setColor(QPalette::Base, QColor(25,25,25)); darkPalette.setColor(QPalette::AlternateBase, QColor(53,53,53)); - darkPalette.setColor(QPalette::ToolTipBase, Theme::white); - darkPalette.setColor(QPalette::ToolTipText, Theme::white); + //darkPalette.setColor(QPalette::ToolTipBase, Theme::white); + //darkPalette.setColor(QPalette::ToolTipText, Theme::white); darkPalette.setColor(QPalette::Text, Theme::white); darkPalette.setColor(QPalette::Disabled, QPalette::Text, Theme::black); darkPalette.setColor(QPalette::Button, QColor(53,53,53)); @@ -36,7 +36,7 @@ int main(int argc, char ** argv) darkPalette.setColor(QPalette::Highlight, Theme::red); darkPalette.setColor(QPalette::HighlightedText, Theme::black); qApp->setPalette(darkPalette); - qApp->setStyleSheet("QToolTip { color: #ffffff; background-color: #fc6621; border: 1px solid white; }"); + //qApp->setStyleSheet("QToolTip { color: #ffffff; background-color: #fc6621; border: 1px solid white; }"); QCoreApplication::setApplicationName(APP_NAME); diff --git a/src/meshgenerator.cpp b/src/meshgenerator.cpp index 29248662..ab237b9a 100644 --- a/src/meshgenerator.cpp +++ b/src/meshgenerator.cpp @@ -36,6 +36,7 @@ void GeneratedCacheContext::updateComponentCombinableMesh(QString componentId, v MeshGenerator::MeshGenerator(Snapshot *snapshot) : m_snapshot(snapshot), + m_isSucceed(false), m_mesh(nullptr), m_outcome(nullptr), m_sharedContextWidget(nullptr), @@ -81,6 +82,11 @@ void MeshGenerator::setSharedContextWidget(QOpenGLWidget *widget) m_sharedContextWidget = widget; } +bool MeshGenerator::isSucceed() +{ + return m_isSucceed; +} + MeshLoader *MeshGenerator::takeResultMesh() { MeshLoader *resultMesh = m_mesh; @@ -697,6 +703,10 @@ void *MeshGenerator::combineComponentMesh(QString componentId, CombineMode *comb cachedComponentPositions.clear(); loadCombinableMeshVerticesPositions(resultMesh, cachedComponentPositions); + if (nullptr == resultMesh) { + m_isSucceed = false; + } + return resultMesh; } @@ -706,6 +716,8 @@ void MeshGenerator::generate() return; QElapsedTimer countTimeConsumed; countTimeConsumed.start(); + + m_isSucceed = true; m_meshliteContext = meshlite_create_context(); diff --git a/src/meshgenerator.h b/src/meshgenerator.h index b87e758b..33ee159a 100644 --- a/src/meshgenerator.h +++ b/src/meshgenerator.h @@ -39,6 +39,7 @@ public: void setGeneratedCacheContext(GeneratedCacheContext *cacheContext); void setSmoothNormal(bool smoothNormal); void setWeldEnabled(bool weldEnabled); + bool isSucceed(); MeshLoader *takeResultMesh(); MeshLoader *takePartPreviewMesh(const QUuid &partId); const std::set &requirePreviewPartIds(); @@ -51,6 +52,7 @@ public slots: void process(); private: Snapshot *m_snapshot; + bool m_isSucceed; MeshLoader *m_mesh; std::map m_partPreviewMeshMap; std::set m_requirePreviewPartIds; diff --git a/src/partwidget.cpp b/src/partwidget.cpp index b6a3e9f7..41a3f10d 100644 --- a/src/partwidget.cpp +++ b/src/partwidget.cpp @@ -21,38 +21,47 @@ PartWidget::PartWidget(const Document *document, QUuid partId) : retainSizePolicy.setRetainSizeWhenHidden(true); m_visibleButton = new QPushButton(); + m_visibleButton->setToolTip(tr("Show/hide nodes")); m_visibleButton->setSizePolicy(retainSizePolicy); initButton(m_visibleButton); m_lockButton = new QPushButton(); + m_lockButton->setToolTip(tr("Lock/unlock nodes")); m_lockButton->setSizePolicy(retainSizePolicy); initButton(m_lockButton); m_subdivButton = new QPushButton(); + m_subdivButton->setToolTip(tr("Square/Round")); m_subdivButton->setSizePolicy(retainSizePolicy); initButton(m_subdivButton); m_disableButton = new QPushButton(); + m_disableButton->setToolTip(tr("Join/Remove from final result")); m_disableButton->setSizePolicy(retainSizePolicy); initButton(m_disableButton); m_xMirrorButton = new QPushButton(); + m_xMirrorButton->setToolTip(tr("Toggle mirror")); m_xMirrorButton->setSizePolicy(retainSizePolicy); initButton(m_xMirrorButton); m_deformButton = new QPushButton(); + m_deformButton->setToolTip(tr("Deform")); m_deformButton->setSizePolicy(retainSizePolicy); initButton(m_deformButton); m_roundButton = new QPushButton; + m_roundButton->setToolTip(tr("Toggle round end")); m_roundButton->setSizePolicy(retainSizePolicy); initButton(m_roundButton); m_colorButton = new QPushButton; + m_colorButton->setToolTip(tr("Color and material picker")); m_colorButton->setSizePolicy(retainSizePolicy); initButton(m_colorButton); m_wrapButton = new QPushButton; + m_wrapButton->setToolTip(tr("Toggle convex wrap")); m_wrapButton->setSizePolicy(retainSizePolicy); initButton(m_wrapButton);