From eeff771a3b752a3a4ae3e90c1fa66db11ac05e7f Mon Sep 17 00:00:00 2001 From: Jeremy Hu Date: Tue, 9 Oct 2018 21:01:04 +0800 Subject: [PATCH] Optimize texture generating time --- src/meshgenerator.cpp | 1 + src/meshresultcontext.h | 1 + src/skeletondocument.cpp | 5 +++ src/skeletondocument.h | 1 + src/skeletondocumentwindow.cpp | 2 ++ src/texturegenerator.cpp | 63 +++++++++++++--------------------- src/texturegenerator.h | 2 +- 7 files changed, 34 insertions(+), 41 deletions(-) diff --git a/src/meshgenerator.cpp b/src/meshgenerator.cpp index adab8f82..6cdf961a 100644 --- a/src/meshgenerator.cpp +++ b/src/meshgenerator.cpp @@ -309,6 +309,7 @@ void *MeshGenerator::combinePartMesh(QString partId) cacheBmeshNodes.push_back(bmeshNode); if (xMirrored) { bmeshNode.partId = mirroredPartId; + bmeshNode.mirrorFromPartId = QUuid(partId); bmeshNode.origin.setX(-x); cacheBmeshNodes.push_back(bmeshNode); } diff --git a/src/meshresultcontext.h b/src/meshresultcontext.h index ff77aed3..9c24bbb4 100644 --- a/src/meshresultcontext.h +++ b/src/meshresultcontext.h @@ -19,6 +19,7 @@ struct BmeshNode QVector3D origin; float radius = 0; Material material; + QUuid mirrorFromPartId; SkeletonBoneMark boneMark; }; diff --git a/src/skeletondocument.cpp b/src/skeletondocument.cpp index c455aa82..4c811adf 100644 --- a/src/skeletondocument.cpp +++ b/src/skeletondocument.cpp @@ -2943,3 +2943,8 @@ void SkeletonDocument::materialPreviewsReady() generateMaterialPreviews(); } +bool SkeletonDocument::isMeshGenerating() const +{ + return nullptr != m_meshGenerator; +} + diff --git a/src/skeletondocument.h b/src/skeletondocument.h index 9f91b818..bded9a5a 100644 --- a/src/skeletondocument.h +++ b/src/skeletondocument.h @@ -613,6 +613,7 @@ public: const std::vector &resultRigErrorMarkNames() const; const MeshResultContext ¤tRiggedResultContext() const; bool currentRigSucceed() const; + bool isMeshGenerating() const; public slots: void removeNode(QUuid nodeId); void removeEdge(QUuid edgeId); diff --git a/src/skeletondocumentwindow.cpp b/src/skeletondocumentwindow.cpp index 3dd7f971..610b233d 100644 --- a/src/skeletondocumentwindow.cpp +++ b/src/skeletondocumentwindow.cpp @@ -822,6 +822,8 @@ SkeletonDocumentWindow::SkeletonDocumentWindow() : connect(m_document, &SkeletonDocument::postProcessedResultChanged, m_document, &SkeletonDocument::generateTexture); //connect(m_document, &SkeletonDocument::resultTextureChanged, m_document, &SkeletonDocument::bakeAmbientOcclusionTexture); connect(m_document, &SkeletonDocument::resultTextureChanged, [=]() { + if (m_document->isMeshGenerating()) + return; m_modelRenderWidget->updateMesh(m_document->takeResultTextureMesh()); }); diff --git a/src/texturegenerator.cpp b/src/texturegenerator.cpp index f4fec217..6d626fd4 100644 --- a/src/texturegenerator.cpp +++ b/src/texturegenerator.cpp @@ -126,10 +126,10 @@ void TextureGenerator::addPartAmbientOcclusionMap(QUuid partId, const QImage *im m_partAmbientOcclusionTextureMap[partId] = *image; } -QPainterPath TextureGenerator::expandedPainterPath(const QPainterPath &painterPath) +QPainterPath TextureGenerator::expandedPainterPath(const QPainterPath &painterPath, int expandSize) { QPainterPathStroker stroker; - stroker.setWidth(3); + stroker.setWidth(expandSize); stroker.setJoinStyle(Qt::MiterJoin); return (stroker.createStroke(painterPath) + painterPath).simplified(); } @@ -153,7 +153,7 @@ void TextureGenerator::prepare() TextureType forWhat = (TextureType)(i + 1); MaterialTextures materialTextures; QUuid materialId = bmeshNode.material.materialId; - auto findUpdatedMaterialIdResult = updatedMaterialIdMap.find(bmeshNode.partId); + auto findUpdatedMaterialIdResult = updatedMaterialIdMap.find(bmeshNode.mirrorFromPartId.isNull() ? bmeshNode.partId : bmeshNode.mirrorFromPartId); if (findUpdatedMaterialIdResult != updatedMaterialIdMap.end()) materialId = findUpdatedMaterialIdResult->second; initializeMaterialTexturesFromSnapshot(*m_snapshot, materialId, materialTextures); @@ -189,6 +189,8 @@ void TextureGenerator::generate() const std::vector &triangleMaterials = m_resultContext->triangleMaterials(); const std::vector &triangleUvs = m_resultContext->triangleUvs(); + auto createImageBeginTime = countTimeConsumed.elapsed(); + m_resultTextureColorImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32); m_resultTextureColorImage->fill(Theme::white); @@ -210,6 +212,8 @@ void TextureGenerator::generate() m_resultTextureAmbientOcclusionImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32); m_resultTextureAmbientOcclusionImage->fill(Qt::transparent); + auto createImageEndTime = countTimeConsumed.elapsed(); + QColor borderColor = Qt::darkGray; QPen pen(borderColor); @@ -242,43 +246,8 @@ void TextureGenerator::generate() textureAmbientOcclusionPainter.begin(m_resultTextureAmbientOcclusionImage); textureAmbientOcclusionPainter.setRenderHint(QPainter::Antialiasing); textureAmbientOcclusionPainter.setRenderHint(QPainter::HighQualityAntialiasing); - - // round 1, paint background - for (auto i = 0u; i < triangleUvs.size(); i++) { - QPainterPath path; - const ResultTriangleUv *uv = &triangleUvs[i]; - for (auto j = 0; j < 3; j++) { - if (0 == j) { - path.moveTo(uv->uv[j][0] * TextureGenerator::m_textureSize, uv->uv[j][1] * TextureGenerator::m_textureSize); - } else { - path.lineTo(uv->uv[j][0] * TextureGenerator::m_textureSize, uv->uv[j][1] * TextureGenerator::m_textureSize); - } - } - path = expandedPainterPath(path); - QPen textureBorderPen(triangleMaterials[i].color); - textureBorderPen.setWidth(32); - texturePainter.setPen(textureBorderPen); - texturePainter.setBrush(QBrush(triangleMaterials[i].color)); - texturePainter.drawPath(path); - } - // round 2.1, color paint - texturePainter.setPen(Qt::NoPen); - for (auto i = 0u; i < triangleUvs.size(); i++) { - QPainterPath path; - const ResultTriangleUv *uv = &triangleUvs[i]; - float points[][2] = { - {uv->uv[0][0] * TextureGenerator::m_textureSize, uv->uv[0][1] * TextureGenerator::m_textureSize}, - {uv->uv[1][0] * TextureGenerator::m_textureSize, uv->uv[1][1] * TextureGenerator::m_textureSize}, - {uv->uv[2][0] * TextureGenerator::m_textureSize, uv->uv[2][1] * TextureGenerator::m_textureSize} - }; - path.moveTo(points[0][0], points[0][1]); - path.lineTo(points[1][0], points[1][1]); - path.lineTo(points[2][0], points[2][1]); - path = expandedPainterPath(path); - // Fill base color - texturePainter.fillPath(path, QBrush(triangleMaterials[i].color)); - } - // round 2.2, texture paint + + auto paintTextureBeginTime = countTimeConsumed.elapsed(); texturePainter.setPen(Qt::NoPen); for (auto i = 0u; i < triangleUvs.size(); i++) { QPainterPath path; @@ -300,6 +269,8 @@ void TextureGenerator::generate() texturePainter.setClipPath(path); texturePainter.drawImage(0, 0, findColorTextureResult->second); texturePainter.setClipping(false); + } else { + texturePainter.fillPath(path, QBrush(triangleMaterials[i].color)); } // Copy normal texture if there is one auto findNormalTextureResult = m_partNormalTextureMap.find(source.first); @@ -338,9 +309,11 @@ void TextureGenerator::generate() hasAmbientOcclusionMap = true; } } + auto paintTextureEndTime = countTimeConsumed.elapsed(); pen.setWidth(0); textureBorderPainter.setPen(pen); + auto paintBorderBeginTime = countTimeConsumed.elapsed(); for (auto i = 0u; i < triangleUvs.size(); i++) { const ResultTriangleUv *uv = &triangleUvs[i]; for (auto j = 0; j < 3; j++) { @@ -350,6 +323,7 @@ void TextureGenerator::generate() uv->uv[to][0] * TextureGenerator::m_textureSize, uv->uv[to][1] * TextureGenerator::m_textureSize); } } + auto paintBorderEndTime = countTimeConsumed.elapsed(); texturePainter.end(); textureBorderPainter.end(); @@ -363,6 +337,7 @@ void TextureGenerator::generate() m_resultTextureNormalImage = nullptr; } + auto mergeMetalnessRoughnessAmbientOcclusionBeginTime = countTimeConsumed.elapsed(); if (!hasMetalnessMap && !hasRoughnessMap && !hasAmbientOcclusionMap) { delete m_resultTextureMetalnessRoughnessAmbientOcclusionImage; m_resultTextureMetalnessRoughnessAmbientOcclusionImage = nullptr; @@ -380,6 +355,7 @@ void TextureGenerator::generate() } } } + auto mergeMetalnessRoughnessAmbientOcclusionEndTime = countTimeConsumed.elapsed(); m_resultTextureImage = new QImage(*m_resultTextureColorImage); @@ -389,6 +365,7 @@ void TextureGenerator::generate() mergeTextureGuidePainter.drawImage(0, 0, *m_resultTextureBorderImage); mergeTextureGuidePainter.end(); + auto createResultBeginTime = countTimeConsumed.elapsed(); m_resultMesh = new MeshLoader(*m_resultContext); m_resultMesh->setTextureImage(new QImage(*m_resultTextureImage)); if (nullptr != m_resultTextureNormalImage) @@ -399,8 +376,14 @@ void TextureGenerator::generate() m_resultMesh->setHasRoughnessInImage(hasRoughnessMap); m_resultMesh->setHasAmbientOcclusionInImage(hasAmbientOcclusionMap); } + auto createResultEndTime = countTimeConsumed.elapsed(); qDebug() << "The texture[" << TextureGenerator::m_textureSize << "x" << TextureGenerator::m_textureSize << "] generation took" << countTimeConsumed.elapsed() << "milliseconds"; + qDebug() << " :create image took" << (createImageEndTime - createImageBeginTime) << "milliseconds"; + qDebug() << " :paint texture took" << (paintTextureEndTime - paintTextureBeginTime) << "milliseconds"; + qDebug() << " :paint border took" << (paintBorderEndTime - paintBorderBeginTime) << "milliseconds"; + qDebug() << " :merge metalness, roughness, and ambient occlusion texture took" << (mergeMetalnessRoughnessAmbientOcclusionEndTime - mergeMetalnessRoughnessAmbientOcclusionBeginTime) << "milliseconds"; + qDebug() << " :create result took" << (createResultEndTime - createResultBeginTime) << "milliseconds"; } void TextureGenerator::process() diff --git a/src/texturegenerator.h b/src/texturegenerator.h index 65198f72..7ff2c327 100644 --- a/src/texturegenerator.h +++ b/src/texturegenerator.h @@ -33,7 +33,7 @@ public: static int m_textureSize; private: void prepare(); - QPainterPath expandedPainterPath(const QPainterPath &painterPath); + QPainterPath expandedPainterPath(const QPainterPath &painterPath, int expandSize=3); private: MeshResultContext *m_resultContext; QImage *m_resultTextureGuideImage;