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 00000000..26023dd4 Binary files /dev/null and b/resources/checkuv.png differ 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; }; }