Add auto colorize from reference image

Thanks @enzyme69 for the idea.
master
Jeremy Hu 2019-10-25 23:41:17 +09:30
parent 12a95f2e8e
commit db9d8c04c0
5 changed files with 126 additions and 6 deletions

View File

@ -1147,6 +1147,18 @@ Tips:
<source>Clear Cut Face</source>
<translation></translation>
</message>
<message>
<source>Blank</source>
<translation></translation>
</message>
<message>
<source>Auto Color</source>
<translation></translation>
</message>
<message>
<source>Colorize</source>
<translation></translation>
</message>
</context>
<context>
<name>UpdatesCheckWidget</name>

View File

@ -900,6 +900,7 @@ DocumentWindow::DocumentWindow() :
connect(graphicsWidget, &SkeletonGraphicsWidget::setPartVisibleState, m_document, &Document::setPartVisibleState);
connect(graphicsWidget, &SkeletonGraphicsWidget::setPartSubdivState, m_document, &Document::setPartSubdivState);
connect(graphicsWidget, &SkeletonGraphicsWidget::setPartChamferState, m_document, &Document::setPartChamferState);
connect(graphicsWidget, &SkeletonGraphicsWidget::setPartColorState, m_document, &Document::setPartColorState);
connect(graphicsWidget, &SkeletonGraphicsWidget::setPartDisableState, m_document, &Document::setPartDisableState);
connect(graphicsWidget, &SkeletonGraphicsWidget::setPartXmirrorState, m_document, &Document::setPartXmirrorState);
connect(graphicsWidget, &SkeletonGraphicsWidget::setPartRoundState, m_document, &Document::setPartRoundState);

View File

@ -11,9 +11,11 @@
void initShortCuts(QWidget *widget, SkeletonGraphicsWidget *graphicsWidget)
{
defineKey(Qt::Key_Escape, &SkeletonGraphicsWidget::shortcutEscape);
defineKey(Qt::Key_Delete, &SkeletonGraphicsWidget::shortcutDelete);
defineKey(Qt::Key_Backspace, &SkeletonGraphicsWidget::shortcutDelete);
defineKey(Qt::Key_A, &SkeletonGraphicsWidget::shortcutAddMode);
defineKey(Qt::CTRL + Qt::Key_A, &SkeletonGraphicsWidget::shortcutSelectAll);
defineKey(Qt::CTRL + Qt::Key_Z, &SkeletonGraphicsWidget::shortcutUndo);
defineKey(Qt::CTRL + Qt::SHIFT + Qt::Key_Z, &SkeletonGraphicsWidget::shortcutRedo);
defineKey(Qt::CTRL + Qt::Key_Y, &SkeletonGraphicsWidget::shortcutRedo);

View File

@ -49,7 +49,8 @@ SkeletonGraphicsWidget::SkeletonGraphicsWidget(const SkeletonDocument *document)
m_nodePositionModifyOnly(false),
m_mainProfileOnly(false),
m_turnaroundOpacity(0.25),
m_rotated(false)
m_rotated(false),
m_backgroundImage(nullptr)
{
setRenderHint(QPainter::Antialiasing, false);
setBackgroundBrush(QBrush(QWidget::palette().color(QWidget::backgroundRole()), Qt::SolidPattern));
@ -95,6 +96,11 @@ SkeletonGraphicsWidget::SkeletonGraphicsWidget(const SkeletonDocument *document)
connect(this, &SkeletonGraphicsWidget::customContextMenuRequested, this, &SkeletonGraphicsWidget::showContextMenu);
}
SkeletonGraphicsWidget::~SkeletonGraphicsWidget()
{
delete m_backgroundImage;
}
void SkeletonGraphicsWidget::setRotated(bool rotated)
{
if (m_rotated == rotated)
@ -126,6 +132,14 @@ void SkeletonGraphicsWidget::setBackgroundBlur(float turnaroundOpacity)
m_backgroundItem->setOpacity(m_turnaroundOpacity);
}
void SkeletonGraphicsWidget::shortcutEscape()
{
if (SkeletonDocumentEditMode::Add == m_document->editMode) {
emit setEditMode(SkeletonDocumentEditMode::Select);
return;
}
}
void SkeletonGraphicsWidget::showContextMenu(const QPoint &pos)
{
if (SkeletonDocumentEditMode::Add == m_document->editMode) {
@ -302,6 +316,18 @@ void SkeletonGraphicsWidget::showContextMenu(const QPoint &pos)
}
}
QAction colorizeAsBlankAction(tr("Blank"), this);
QAction colorizeAsAutoColorAction(tr("Auto Color"), this);
if (!m_nodePositionModifyOnly && hasNodeSelection()) {
QMenu *subMenu = contextMenu.addMenu(tr("Colorize"));
connect(&colorizeAsBlankAction, &QAction::triggered, this, &SkeletonGraphicsWidget::fadeSelected);
subMenu->addAction(&colorizeAsBlankAction);
connect(&colorizeAsAutoColorAction, &QAction::triggered, this, &SkeletonGraphicsWidget::colorizeSelected);
subMenu->addAction(&colorizeAsAutoColorAction);
}
QAction selectAllAction(tr("Select All"), this);
if (hasItems()) {
connect(&selectAllAction, &QAction::triggered, this, &SkeletonGraphicsWidget::selectAll);
@ -396,6 +422,72 @@ bool SkeletonGraphicsWidget::hasCutFaceAdjustedNodesSelection()
return false;
}
void SkeletonGraphicsWidget::fadeSelected()
{
std::set<QUuid> partIds;
for (const auto &it: m_rangeSelectionSet) {
if (it->data(0) == "node") {
SkeletonGraphicsNodeItem *nodeItem = (SkeletonGraphicsNodeItem *)it;
const SkeletonNode *node = m_document->findNode(nodeItem->id());
if (nullptr == node)
continue;
if (partIds.find(node->partId) != partIds.end())
continue;
partIds.insert(node->partId);
}
}
if (partIds.empty())
return;
emit batchChangeBegin();
for (const auto &it: partIds) {
emit setPartColorState(it, false, Qt::white);
}
emit batchChangeEnd();
emit groupOperationAdded();
}
void SkeletonGraphicsWidget::colorizeSelected()
{
if (nullptr == m_backgroundImage)
return;
std::map<QUuid, std::map<QString, size_t>> sumOfColor;
for (const auto &it: m_rangeSelectionSet) {
if (it->data(0) == "node") {
SkeletonGraphicsNodeItem *nodeItem = (SkeletonGraphicsNodeItem *)it;
const SkeletonNode *node = m_document->findNode(nodeItem->id());
if (nullptr == node)
continue;
const auto &position = nodeItem->origin();
sumOfColor[node->partId][m_backgroundImage->pixelColor(position.x(), position.y()).name()]++;
} else if (it->data(0) == "edge") {
SkeletonGraphicsEdgeItem *edgeItem = (SkeletonGraphicsEdgeItem *)it;
const SkeletonEdge *edge = m_document->findEdge(edgeItem->id());
if (nullptr == edge)
continue;
const auto position = (edgeItem->firstItem()->origin() + edgeItem->secondItem()->origin()) / 2;
sumOfColor[edge->partId][m_backgroundImage->pixelColor(position.x(), position.y()).name()]++;
}
}
if (sumOfColor.empty())
return;
emit batchChangeBegin();
for (const auto &it: sumOfColor) {
int r = 0;
int g = 0;
int b = 0;
for (const auto &freq: it.second) {
QColor color(freq.first);
r += color.red();
g += color.green();
b += color.blue();
}
QColor color(r / it.second.size(), g / it.second.size(), b / it.second.size());
emit setPartColorState(it.first, true, color);
}
emit batchChangeEnd();
emit groupOperationAdded();
}
void SkeletonGraphicsWidget::breakSelected()
{
std::set<QUuid> edgeIds;
@ -592,17 +684,17 @@ void SkeletonGraphicsWidget::updateTurnaround()
void SkeletonGraphicsWidget::turnaroundImageReady()
{
QImage *backgroundImage = m_turnaroundLoader->takeResultImage();
if (backgroundImage && backgroundImage->width() > 0 && backgroundImage->height() > 0) {
delete m_backgroundImage;
m_backgroundImage = m_turnaroundLoader->takeResultImage();
if (m_backgroundImage && m_backgroundImage->width() > 0 && m_backgroundImage->height() > 0) {
//qDebug() << "Fit turnaround finished with image size:" << backgroundImage->size();
setFixedSize(backgroundImage->size());
setFixedSize(m_backgroundImage->size());
scene()->setSceneRect(rect());
m_backgroundItem->setPixmap(QPixmap::fromImage(*backgroundImage));
m_backgroundItem->setPixmap(QPixmap::fromImage(*m_backgroundImage));
updateItems();
} else {
qDebug() << "Fit turnaround failed";
}
delete backgroundImage;
delete m_turnaroundLoader;
m_turnaroundLoader = nullptr;
@ -1830,6 +1922,11 @@ void SkeletonGraphicsWidget::shortcutChamferedOrNotSelectedPart()
}
}
void SkeletonGraphicsWidget::shortcutSelectAll()
{
selectAll();
}
void SkeletonGraphicsWidget::shortcutRoundEndOrNotSelectedPart()
{
if (SkeletonDocumentEditMode::Select == m_document->editMode && !m_lastCheckedPart.isNull()) {

View File

@ -389,6 +389,8 @@ private:
class SkeletonGraphicsWidget : public QGraphicsView
{
Q_OBJECT
public:
~SkeletonGraphicsWidget();
signals:
void addNode(float x, float y, float z, float radius, QUuid fromNodeId);
void scaleNodeByAddRadius(QUuid nodeId, float amount);
@ -420,6 +422,7 @@ signals:
void setPartRoundState(QUuid partId, bool rounded);
void setPartWrapState(QUuid partId, bool wrapped);
void setPartChamferState(QUuid partId, bool chamfered);
void setPartColorState(QUuid partId, bool hasColor, QColor color);
void setXlockState(bool locked);
void setYlockState(bool locked);
void setZlockState(bool locked);
@ -506,6 +509,8 @@ public slots:
void rotateAllMainProfileClockwise90DegreeAlongOrigin();
void rotateAllMainProfileCounterclockwise90DegreeAlongOrigin();
void removeAllContent();
void fadeSelected();
void colorizeSelected();
void breakSelected();
void connectSelected();
void rotateSelected(int degree);
@ -569,6 +574,8 @@ public slots:
void shortcutRoundEndOrNotSelectedPart();
void shortcutCheckPartComponent();
void shortcutChamferedOrNotSelectedPart();
void shortcutSelectAll();
void shortcutEscape();
private slots:
void turnaroundImageReady();
private:
@ -628,6 +635,7 @@ private: //need initalize
bool m_mainProfileOnly;
float m_turnaroundOpacity;
bool m_rotated;
QImage *m_backgroundImage;
private:
QVector3D m_ikMoveTarget;
QUuid m_ikMoveEndEffectorId;