From 13db7ee97b32a9ac5f1989c570ad96667421fa32 Mon Sep 17 00:00:00 2001 From: Jeremy Hu Date: Sat, 10 Aug 2019 07:57:26 +0930 Subject: [PATCH] Add check UV --- languages/dust3d_zh_CN.ts | 4 ++ resources.qrc | 1 + resources/checkuv.png | Bin 0 -> 43953 bytes src/documentwindow.cpp | 6 +++ src/documentwindow.h | 1 + src/modelmeshbinder.cpp | 40 ++++++++++++++++++- src/modelmeshbinder.h | 5 +++ src/modelwidget.cpp | 11 ++++- src/modelwidget.h | 1 + thirdparty/simpleuv/simpleuv/uvunwrapper.cpp | 2 +- thirdparty/simpleuv/simpleuv/uvunwrapper.h | 1 + 11 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 resources/checkuv.png diff --git a/languages/dust3d_zh_CN.ts b/languages/dust3d_zh_CN.ts index 704f62b3..a2ea055f 100644 --- a/languages/dust3d_zh_CN.ts +++ b/languages/dust3d_zh_CN.ts @@ -366,6 +366,10 @@ Tips: Paint brush 画刷 + + Toggle UV Check + 切换UV检查 + ExportPreviewWidget diff --git a/resources.qrc b/resources.qrc index bb041a06..ae107efc 100644 --- a/resources.qrc +++ b/resources.qrc @@ -20,6 +20,7 @@ resources/hexagon.png resources/heptagon.png resources/userdefined.png + resources/checkuv.png shaders/default.vert shaders/default.frag shaders/default.core.vert diff --git a/resources/checkuv.png b/resources/checkuv.png new file mode 100644 index 0000000000000000000000000000000000000000..26023dd42f271f0e8271dfb1ddd89ab2764dc6dd GIT binary patch literal 43953 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 literal 0 HcmV?d00001 diff --git a/src/documentwindow.cpp b/src/documentwindow.cpp index 7553454b..b5db9a12 100644 --- a/src/documentwindow.cpp +++ b/src/documentwindow.cpp @@ -651,6 +651,12 @@ DocumentWindow::DocumentWindow() : m_modelRenderWidget->toggleWireframe(); }); m_viewMenu->addAction(m_toggleWireframeAction); + + m_toggleUvCheckAction = new QAction(tr("Toggle UV Check"), this); + connect(m_toggleUvCheckAction, &QAction::triggered, [=]() { + m_modelRenderWidget->toggleUvCheck(); + }); + m_viewMenu->addAction(m_toggleUvCheckAction); connect(m_viewMenu, &QMenu::aboutToShow, [=]() { m_resetModelWidgetPosAction->setEnabled(!isModelSitInVisibleArea(m_modelRenderWidget)); diff --git a/src/documentwindow.h b/src/documentwindow.h index 339d9354..a7f5faec 100644 --- a/src/documentwindow.h +++ b/src/documentwindow.h @@ -154,6 +154,7 @@ private: QMenu *m_viewMenu; QAction *m_resetModelWidgetPosAction; QAction *m_toggleWireframeAction; + QAction *m_toggleUvCheckAction; QAction *m_showMotionsListAction; QMenu *m_windowMenu; diff --git a/src/modelmeshbinder.cpp b/src/modelmeshbinder.cpp index f8bbc2cb..061f41b3 100644 --- a/src/modelmeshbinder.cpp +++ b/src/modelmeshbinder.cpp @@ -32,6 +32,19 @@ void ModelMeshBinder::updateMesh(MeshLoader *mesh) } } +void ModelMeshBinder::reloadMesh() +{ + MeshLoader *mesh = nullptr; + { + QMutexLocker lock(&m_newMeshMutex); + if (nullptr == m_mesh) + return; + mesh = new MeshLoader(*m_mesh); + } + if (nullptr != mesh) + updateMesh(mesh); +} + void ModelMeshBinder::initialize() { m_vaoTriangle.create(); @@ -63,8 +76,16 @@ void ModelMeshBinder::paint(ModelShaderProgram *program) m_hasTexture = nullptr != m_mesh->textureImage(); delete m_texture; m_texture = nullptr; - if (m_hasTexture) - m_texture = new QOpenGLTexture(*m_mesh->textureImage()); + if (m_hasTexture) { + if (m_checkUvEnabled) { + static QImage *s_checkUv = nullptr; + if (nullptr == s_checkUv) + s_checkUv = new QImage(":/resources/checkuv.png"); + m_texture = new QOpenGLTexture(*s_checkUv); + } else { + m_texture = new QOpenGLTexture(*m_mesh->textureImage()); + } + } m_hasNormalMap = nullptr != m_mesh->normalMapImage(); delete m_normalMap; @@ -253,3 +274,18 @@ bool ModelMeshBinder::isWireframesVisible() { return m_showWireframes; } + +void ModelMeshBinder::enableCheckUv() +{ + m_checkUvEnabled = true; +} + +void ModelMeshBinder::disableCheckUv() +{ + m_checkUvEnabled = false; +} + +bool ModelMeshBinder::isCheckUvEnabled() +{ + return m_checkUvEnabled; +} diff --git a/src/modelmeshbinder.h b/src/modelmeshbinder.h index 64cdc2f0..de4eb113 100644 --- a/src/modelmeshbinder.h +++ b/src/modelmeshbinder.h @@ -20,6 +20,10 @@ public: void showWireframes(); void hideWireframes(); bool isWireframesVisible(); + void enableCheckUv(); + void disableCheckUv(); + bool isCheckUvEnabled(); + void reloadMesh(); private: MeshLoader *m_mesh = nullptr; MeshLoader *m_newMesh = nullptr; @@ -37,6 +41,7 @@ private: bool m_hasAmbientOcclusionMap = false; QOpenGLTexture *m_metalnessRoughnessAmbientOcclusionMap = nullptr; bool m_toolEnabled = false; + bool m_checkUvEnabled = false; private: QOpenGLVertexArrayObject m_vaoTriangle; QOpenGLBuffer m_vboTriangle; diff --git a/src/modelwidget.cpp b/src/modelwidget.cpp index d0d2dc8c..3fc4f4ac 100644 --- a/src/modelwidget.cpp +++ b/src/modelwidget.cpp @@ -194,7 +194,6 @@ std::pair ModelWidget::screenPositionToMouseRay(const QPoi auto viewPort = QRect(0, 0, width(), height()); auto nearPosition = nearScreen.unproject(modelView, m_projection, viewPort); auto farPosition = farScreen.unproject(modelView, m_projection, viewPort); - qDebug() << "near:" << nearPosition << "far:" << farPosition << "x:" << x << "y:" << y; return std::make_pair(nearPosition, farPosition); } @@ -207,6 +206,16 @@ void ModelWidget::toggleWireframe() update(); } +void ModelWidget::toggleUvCheck() +{ + if (m_meshBinder.isCheckUvEnabled()) + m_meshBinder.disableCheckUv(); + else + m_meshBinder.enableCheckUv(); + m_meshBinder.reloadMesh(); + update(); +} + bool ModelWidget::inputMousePressEventFromOtherWidget(QMouseEvent *event) { bool shouldStartMove = false; diff --git a/src/modelwidget.h b/src/modelwidget.h index ddc964c7..c6baff80 100644 --- a/src/modelwidget.h +++ b/src/modelwidget.h @@ -33,6 +33,7 @@ public: void updateMesh(MeshLoader *mesh); void setGraphicsFunctions(SkeletonGraphicsFunctions *graphicsFunctions); void toggleWireframe(); + void toggleUvCheck(); void enableMove(bool enabled); void enableZoom(bool enabled); void enableMousePicking(bool enabled); diff --git a/thirdparty/simpleuv/simpleuv/uvunwrapper.cpp b/thirdparty/simpleuv/simpleuv/uvunwrapper.cpp index 48759258..1b63b809 100644 --- a/thirdparty/simpleuv/simpleuv/uvunwrapper.cpp +++ b/thirdparty/simpleuv/simpleuv/uvunwrapper.cpp @@ -83,7 +83,7 @@ void UvUnwrapper::splitPartitionToIslands(const std::vector &group, std: continue; if (segmentByNormal) { if (dotProduct(m_mesh.faceNormals[findOppositeFaceResult->second], - m_mesh.faceNormals[index]) < m_segmentDotProductThreshold) { + m_mesh.faceNormals[m_segmentPreferMorePieces ? indexInGroup : index]) < m_segmentDotProductThreshold) { continue; } } diff --git a/thirdparty/simpleuv/simpleuv/uvunwrapper.h b/thirdparty/simpleuv/simpleuv/uvunwrapper.h index c6d37abb..c057a86f 100644 --- a/thirdparty/simpleuv/simpleuv/uvunwrapper.h +++ b/thirdparty/simpleuv/simpleuv/uvunwrapper.h @@ -60,6 +60,7 @@ private: float m_segmentDotProductThreshold = 0.00; float m_texelSizePerUnit = 1.0; float m_resultTextureSize = 0; + bool m_segmentPreferMorePieces = false; }; }