Add "combineMode" configuration for component to replace the "inverse" attribute
Currently, only support "Normal" and "Inversion" modes, "Normal" means normal mesh union, "Inversion" means mesh diff, it behaves like subtract itself from the previous mesh.master
parent
724e745f2e
commit
ab97615bea
|
@ -291,6 +291,9 @@ HEADERS += src/skeletondocument.h
|
|||
SOURCES += src/posedocument.cpp
|
||||
HEADERS += src/posedocument.h
|
||||
|
||||
SOURCES += src/combinemode.cpp
|
||||
HEADERS += src/combinemode.h
|
||||
|
||||
SOURCES += src/main.cpp
|
||||
|
||||
HEADERS += src/version.h
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
#include <QObject>
|
||||
#include "combinemode.h"
|
||||
|
||||
IMPL_CombineModeToString
|
||||
IMPL_CombineModeFromString
|
||||
IMPL_CombineModeToDispName
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef DUST3D_COMBINE_MODE_H
|
||||
#define DUST3D_COMBINE_MODE_H
|
||||
#include <QString>
|
||||
|
||||
enum class CombineMode
|
||||
{
|
||||
Normal = 0,
|
||||
Inversion,
|
||||
Count
|
||||
};
|
||||
CombineMode CombineModeFromString(const char *modeString);
|
||||
#define IMPL_CombineModeFromString \
|
||||
CombineMode CombineModeFromString(const char *modeString) \
|
||||
{ \
|
||||
QString mode = modeString; \
|
||||
if (mode == "Normal") \
|
||||
return CombineMode::Normal; \
|
||||
if (mode == "Inversion") \
|
||||
return CombineMode::Inversion; \
|
||||
return CombineMode::Normal; \
|
||||
}
|
||||
const char *CombineModeToString(CombineMode mode);
|
||||
#define IMPL_CombineModeToString \
|
||||
const char *CombineModeToString(CombineMode mode) \
|
||||
{ \
|
||||
switch (mode) { \
|
||||
case CombineMode::Normal: \
|
||||
return "Normal"; \
|
||||
case CombineMode::Inversion: \
|
||||
return "Inversion"; \
|
||||
default: \
|
||||
return "Normal"; \
|
||||
} \
|
||||
}
|
||||
QString CombineModeToDispName(CombineMode mode);
|
||||
#define IMPL_CombineModeToDispName \
|
||||
QString CombineModeToDispName(CombineMode mode) \
|
||||
{ \
|
||||
switch (mode) { \
|
||||
case CombineMode::Normal: \
|
||||
return QObject::tr("Normal"); \
|
||||
case CombineMode::Inversion: \
|
||||
return QObject::tr("Inversion"); \
|
||||
default: \
|
||||
return QObject::tr("Normal"); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif
|
|
@ -903,7 +903,7 @@ void Document::toSnapshot(Snapshot *snapshot, const std::set<QUuid> &limitNodeId
|
|||
if (!componentIt.second.name.isEmpty())
|
||||
component["name"] = componentIt.second.name;
|
||||
component["expanded"] = componentIt.second.expanded ? "true" : "false";
|
||||
component["inverse"] = componentIt.second.inverse ? "true" : "false";
|
||||
component["combineMode"] = CombineModeToString(componentIt.second.combineMode);
|
||||
component["dirty"] = componentIt.second.dirty ? "true" : "false";
|
||||
if (componentIt.second.smoothAllAdjusted())
|
||||
component["smoothAll"] = QString::number(componentIt.second.smoothAll);
|
||||
|
@ -1178,7 +1178,11 @@ void Document::addFromSnapshot(const Snapshot &snapshot, bool fromPaste)
|
|||
oldNewIdMap[QUuid(componentKv.first)] = component.id;
|
||||
component.name = valueOfKeyInMapOrEmpty(componentKv.second, "name");
|
||||
component.expanded = isTrueValueString(valueOfKeyInMapOrEmpty(componentKv.second, "expanded"));
|
||||
component.inverse = isTrueValueString(valueOfKeyInMapOrEmpty(componentKv.second, "inverse"));
|
||||
component.combineMode = CombineModeFromString(valueOfKeyInMapOrEmpty(componentKv.second, "combineMode").toUtf8().constData());
|
||||
if (component.combineMode == CombineMode::Normal) {
|
||||
if (isTrueValueString(valueOfKeyInMapOrEmpty(componentKv.second, "inverse")))
|
||||
component.combineMode = CombineMode::Inversion;
|
||||
}
|
||||
const auto &smoothAllIt = componentKv.second.find("smoothAll");
|
||||
if (smoothAllIt != componentKv.second.end())
|
||||
component.setSmoothAll(smoothAllIt->second.toFloat());
|
||||
|
@ -1192,7 +1196,7 @@ void Document::addFromSnapshot(const Snapshot &snapshot, bool fromPaste)
|
|||
//qDebug() << "Add part:" << partId << " from component:" << component.id;
|
||||
partMap[partId].componentId = component.id;
|
||||
if (inversePartIds.find(partId) != inversePartIds.end())
|
||||
component.inverse = true;
|
||||
component.combineMode = CombineMode::Inversion;
|
||||
}
|
||||
componentMap[component.id] = component;
|
||||
newAddedComponentIds.insert(component.id);
|
||||
|
@ -1609,18 +1613,18 @@ void Document::setPartVisibleState(QUuid partId, bool visible)
|
|||
emit optionsChanged();
|
||||
}
|
||||
|
||||
void Document::setComponentInverseState(QUuid componentId, bool inverse)
|
||||
void Document::setComponentCombineMode(QUuid componentId, CombineMode combineMode)
|
||||
{
|
||||
auto component = componentMap.find(componentId);
|
||||
if (component == componentMap.end()) {
|
||||
qDebug() << "Component not found:" << componentId;
|
||||
return;
|
||||
}
|
||||
if (component->second.inverse == inverse)
|
||||
if (component->second.combineMode == combineMode)
|
||||
return;
|
||||
component->second.inverse = inverse;
|
||||
component->second.combineMode = combineMode;
|
||||
component->second.dirty = true;
|
||||
emit componentInverseStateChanged(componentId);
|
||||
emit componentCombineModeChanged(componentId);
|
||||
emit skeletonChanged();
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "interpolationtype.h"
|
||||
#include "jointnodetree.h"
|
||||
#include "skeletondocument.h"
|
||||
#include "combinemode.h"
|
||||
|
||||
class MaterialPreviewsGenerator;
|
||||
class MotionsGenerator;
|
||||
|
@ -55,7 +56,7 @@ public:
|
|||
QUuid linkToPartId;
|
||||
QUuid parentId;
|
||||
bool expanded = true;
|
||||
bool inverse = false;
|
||||
CombineMode combineMode = CombineMode::Normal;
|
||||
bool dirty = true;
|
||||
float smoothAll = 0.0;
|
||||
float smoothSeam = 0.0;
|
||||
|
@ -401,7 +402,7 @@ signals:
|
|||
void partColorStateChanged(QUuid partId);
|
||||
void partWrapStateChanged(QUuid partId);
|
||||
void partMaterialIdChanged(QUuid partId);
|
||||
void componentInverseStateChanged(QUuid partId);
|
||||
void componentCombineModeChanged(QUuid componentId);
|
||||
void cleanup();
|
||||
void originChanged();
|
||||
void xlockStateChanged();
|
||||
|
@ -549,7 +550,7 @@ public slots:
|
|||
void setPartColorState(QUuid partId, bool hasColor, QColor color);
|
||||
void setPartWrapState(QUuid partId, bool wrapped);
|
||||
void setPartMaterialId(QUuid partId, QUuid materialId);
|
||||
void setComponentInverseState(QUuid componentId, bool inverse);
|
||||
void setComponentCombineMode(QUuid componentId, CombineMode combineMode);
|
||||
void moveComponentUp(QUuid componentId);
|
||||
void moveComponentDown(QUuid componentId);
|
||||
void moveComponentToTop(QUuid componentId);
|
||||
|
|
|
@ -783,7 +783,7 @@ DocumentWindow::DocumentWindow() :
|
|||
connect(partTreeWidget, &PartTreeWidget::unlockAllComponents, m_document, &Document::unlockAllComponents);
|
||||
connect(partTreeWidget, &PartTreeWidget::setPartLockState, m_document, &Document::setPartLockState);
|
||||
connect(partTreeWidget, &PartTreeWidget::setPartVisibleState, m_document, &Document::setPartVisibleState);
|
||||
connect(partTreeWidget, &PartTreeWidget::setComponentInverseState, m_document, &Document::setComponentInverseState);
|
||||
connect(partTreeWidget, &PartTreeWidget::setComponentCombineMode, m_document, &Document::setComponentCombineMode);
|
||||
connect(partTreeWidget, &PartTreeWidget::hideDescendantComponents, m_document, &Document::hideDescendantComponents);
|
||||
connect(partTreeWidget, &PartTreeWidget::showDescendantComponents, m_document, &Document::showDescendantComponents);
|
||||
connect(partTreeWidget, &PartTreeWidget::lockDescendantComponents, m_document, &Document::lockDescendantComponents);
|
||||
|
@ -796,7 +796,7 @@ DocumentWindow::DocumentWindow() :
|
|||
connect(m_document, &Document::componentRemoved, partTreeWidget, &PartTreeWidget::componentRemoved);
|
||||
connect(m_document, &Document::componentAdded, partTreeWidget, &PartTreeWidget::componentAdded);
|
||||
connect(m_document, &Document::componentExpandStateChanged, partTreeWidget, &PartTreeWidget::componentExpandStateChanged);
|
||||
connect(m_document, &Document::componentInverseStateChanged, partTreeWidget, &PartTreeWidget::componentInverseStateChanged);
|
||||
connect(m_document, &Document::componentCombineModeChanged, partTreeWidget, &PartTreeWidget::componentCombineModeChanged);
|
||||
connect(m_document, &Document::partPreviewChanged, partTreeWidget, &PartTreeWidget::partPreviewChanged);
|
||||
connect(m_document, &Document::partLockStateChanged, partTreeWidget, &PartTreeWidget::partLockStateChanged);
|
||||
connect(m_document, &Document::partVisibleStateChanged, partTreeWidget, &PartTreeWidget::partVisibleStateChanged);
|
||||
|
|
|
@ -516,7 +516,8 @@ void *MeshGenerator::combineComponentMesh(QString componentId, bool *inverse)
|
|||
component = &findComponent->second;
|
||||
}
|
||||
|
||||
if (isTrueValueString(valueOfKeyInMapOrEmpty(*component, "inverse")))
|
||||
CombineMode combineMode = CombineModeFromString(valueOfKeyInMapOrEmpty(*component, "combineMode").toUtf8().constData());
|
||||
if (combineMode == CombineMode::Inversion)
|
||||
*inverse = true;
|
||||
|
||||
if (m_dirtyComponentIds.find(componentId) == m_dirtyComponentIds.end()) {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <QRadialGradient>
|
||||
#include <QBrush>
|
||||
#include <QGuiApplication>
|
||||
#include <QComboBox>
|
||||
#include "parttreewidget.h"
|
||||
#include "partwidget.h"
|
||||
#include "skeletongraphicswidget.h"
|
||||
|
@ -119,8 +120,8 @@ void PartTreeWidget::updateComponentSelectState(QUuid componentId, bool selected
|
|||
auto item = m_partItemMap.find(component->linkToPartId);
|
||||
if (item != m_componentItemMap.end()) {
|
||||
PartWidget *widget = (PartWidget *)itemWidget(item->second, 0);
|
||||
// Inverse state updating call should be called before check state updating call
|
||||
widget->updateInverseState(component->inverse);
|
||||
// Unnormal state updating call should be called before check state updating call
|
||||
widget->updateUnnormalState(component->combineMode != CombineMode::Normal);
|
||||
widget->updateCheckedState(selected);
|
||||
}
|
||||
return;
|
||||
|
@ -128,7 +129,7 @@ void PartTreeWidget::updateComponentSelectState(QUuid componentId, bool selected
|
|||
auto item = m_componentItemMap.find(componentId);
|
||||
if (item != m_componentItemMap.end()) {
|
||||
item->second->setFont(0, selected ? m_selectedFont : m_normalFont);
|
||||
if (component->inverse)
|
||||
if (component->combineMode != CombineMode::Normal)
|
||||
item->second->setForeground(0, selected ? QBrush(Theme::blue) : QBrush(Theme::blue));
|
||||
else
|
||||
item->second->setForeground(0, selected ? QBrush(Theme::red) : QBrush(Theme::white));
|
||||
|
@ -259,7 +260,7 @@ void PartTreeWidget::showContextMenu(const QPoint &pos)
|
|||
} else {
|
||||
QLabel *previewLabel = new QLabel;
|
||||
previewLabel->setFixedHeight(Theme::partPreviewImageSize);
|
||||
previewLabel->setStyleSheet("QLabel {color: " + (component && component->inverse ? Theme::blue.name() : Theme::red.name()) + "}");
|
||||
previewLabel->setStyleSheet("QLabel {color: " + (component && (component->combineMode != CombineMode::Normal) ? Theme::blue.name() : Theme::red.name()) + "}");
|
||||
if (nullptr != component) {
|
||||
previewLabel->setText(component->name);
|
||||
} else if (!componentIds.empty()) {
|
||||
|
@ -268,7 +269,31 @@ void PartTreeWidget::showContextMenu(const QPoint &pos)
|
|||
layout->addWidget(previewLabel);
|
||||
}
|
||||
QWidget *widget = new QWidget;
|
||||
if (nullptr != component) {
|
||||
QComboBox *combineModeSelectBox = new QComboBox;
|
||||
for (size_t i = 0; i < (size_t)CombineMode::Count; ++i) {
|
||||
CombineMode mode = (CombineMode)i;
|
||||
combineModeSelectBox->addItem(CombineModeToDispName(mode));
|
||||
}
|
||||
combineModeSelectBox->setCurrentIndex((int)component->combineMode);
|
||||
|
||||
connect(combineModeSelectBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, [=](int index) {
|
||||
emit setComponentCombineMode(component->id, (CombineMode)index);
|
||||
});
|
||||
|
||||
QHBoxLayout *combineModeLayout = new QHBoxLayout;
|
||||
combineModeLayout->setAlignment(Qt::AlignCenter);
|
||||
combineModeLayout->setContentsMargins(0, 0, 0, 0);
|
||||
combineModeLayout->setSpacing(0);
|
||||
combineModeLayout->addWidget(combineModeSelectBox);
|
||||
|
||||
QVBoxLayout *newLayout = new QVBoxLayout;
|
||||
newLayout->addLayout(layout);
|
||||
newLayout->addLayout(combineModeLayout);
|
||||
widget->setLayout(newLayout);
|
||||
} else {
|
||||
widget->setLayout(layout);
|
||||
}
|
||||
forDisplayPartImage.setDefaultWidget(widget);
|
||||
if (!componentIds.empty()) {
|
||||
contextMenu.addAction(&forDisplayPartImage);
|
||||
|
@ -283,8 +308,6 @@ void PartTreeWidget::showContextMenu(const QPoint &pos)
|
|||
lockAction.setIcon(Theme::awesome()->icon(fa::lock));
|
||||
QAction unlockAction(tr("Unlock"), this);
|
||||
unlockAction.setIcon(Theme::awesome()->icon(fa::unlock));
|
||||
QAction invertAction(tr("Invert"), this);
|
||||
QAction cancelInverseAction(tr("Cancel Inverse"), this);
|
||||
QAction selectAction(tr("Select"), this);
|
||||
|
||||
if (nullptr != component && nullptr != part) {
|
||||
|
@ -353,6 +376,7 @@ void PartTreeWidget::showContextMenu(const QPoint &pos)
|
|||
contextMenu.addAction(&unlockAction);
|
||||
}
|
||||
|
||||
/*
|
||||
if (component && !component->inverse) {
|
||||
connect(&invertAction, &QAction::triggered, [=]() {
|
||||
emit setComponentInverseState(component->id, true);
|
||||
|
@ -366,6 +390,7 @@ void PartTreeWidget::showContextMenu(const QPoint &pos)
|
|||
});
|
||||
contextMenu.addAction(&cancelInverseAction);
|
||||
}
|
||||
*/
|
||||
|
||||
contextMenu.addSeparator();
|
||||
|
||||
|
@ -655,7 +680,7 @@ void PartTreeWidget::componentExpandStateChanged(QUuid componentId)
|
|||
componentItem->second->setExpanded(component->expanded);
|
||||
}
|
||||
|
||||
void PartTreeWidget::componentInverseStateChanged(QUuid componentId)
|
||||
void PartTreeWidget::componentCombineModeChanged(QUuid componentId)
|
||||
{
|
||||
updateComponentAppearance(componentId);
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ signals:
|
|||
void unlockAllComponents();
|
||||
void setPartLockState(QUuid partId, bool locked);
|
||||
void setPartVisibleState(QUuid partId, bool visible);
|
||||
void setComponentInverseState(QUuid componentId, bool inverse);
|
||||
void setComponentCombineMode(QUuid componentId, CombineMode combineMode);
|
||||
void hideDescendantComponents(QUuid componentId);
|
||||
void showDescendantComponents(QUuid componentId);
|
||||
void lockDescendantComponents(QUuid componentId);
|
||||
|
@ -49,7 +49,7 @@ public slots:
|
|||
void componentRemoved(QUuid componentId);
|
||||
void componentAdded(QUuid componentId);
|
||||
void componentExpandStateChanged(QUuid componentId);
|
||||
void componentInverseStateChanged(QUuid componentId);
|
||||
void componentCombineModeChanged(QUuid componentId);
|
||||
void partRemoved(QUuid partId);
|
||||
void partPreviewChanged(QUuid partid);
|
||||
void partLockStateChanged(QUuid partId);
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
PartWidget::PartWidget(const Document *document, QUuid partId) :
|
||||
m_document(document),
|
||||
m_partId(partId),
|
||||
m_inverted(false)
|
||||
m_unnormal(false)
|
||||
{
|
||||
QSizePolicy retainSizePolicy = sizePolicy();
|
||||
retainSizePolicy.setRetainSizeWhenHidden(true);
|
||||
|
@ -263,17 +263,17 @@ void PartWidget::updateAllButtons()
|
|||
void PartWidget::updateCheckedState(bool checked)
|
||||
{
|
||||
if (checked)
|
||||
m_backgroundWidget->setStyleSheet("QWidget#background {border: 1px solid " + (m_inverted ? Theme::blue.name() : Theme::red.name()) + ";}");
|
||||
m_backgroundWidget->setStyleSheet("QWidget#background {border: 1px solid " + (m_unnormal ? Theme::blue.name() : Theme::red.name()) + ";}");
|
||||
else
|
||||
m_backgroundWidget->setStyleSheet("QWidget#background {border: 1px solid transparent;}");
|
||||
}
|
||||
|
||||
void PartWidget::updateInverseState(bool inverse)
|
||||
void PartWidget::updateUnnormalState(bool unnormal)
|
||||
{
|
||||
if (m_inverted == inverse)
|
||||
if (m_unnormal == unnormal)
|
||||
return;
|
||||
|
||||
m_inverted = inverse;
|
||||
m_unnormal = unnormal;
|
||||
updateAllButtons();
|
||||
}
|
||||
|
||||
|
@ -439,7 +439,7 @@ void PartWidget::initButton(QPushButton *button)
|
|||
|
||||
void PartWidget::updateButton(QPushButton *button, QChar icon, bool highlighted)
|
||||
{
|
||||
Theme::updateAwesomeMiniButton(button, icon, highlighted, m_inverted);
|
||||
Theme::updateAwesomeMiniButton(button, icon, highlighted, m_unnormal);
|
||||
}
|
||||
|
||||
void PartWidget::updatePreview()
|
||||
|
|
|
@ -45,7 +45,7 @@ public:
|
|||
void updateColorButton();
|
||||
void updateWrapButton();
|
||||
void updateCheckedState(bool checked);
|
||||
void updateInverseState(bool inverse);
|
||||
void updateUnnormalState(bool unnormal);
|
||||
static QSize preferredSize();
|
||||
ModelWidget *previewWidget();
|
||||
protected:
|
||||
|
@ -56,7 +56,7 @@ public slots:
|
|||
private: // need initialize
|
||||
const Document *m_document;
|
||||
QUuid m_partId;
|
||||
bool m_inverted;
|
||||
bool m_unnormal;
|
||||
private:
|
||||
ModelWidget *m_previewWidget;
|
||||
QPushButton *m_visibleButton;
|
||||
|
|
|
@ -103,14 +103,14 @@ void Theme::initAwesomeMiniButton(QPushButton *button)
|
|||
button->setFocusPolicy(Qt::NoFocus);
|
||||
}
|
||||
|
||||
void Theme::updateAwesomeMiniButton(QPushButton *button, QChar icon, bool highlighted, bool inverted)
|
||||
void Theme::updateAwesomeMiniButton(QPushButton *button, QChar icon, bool highlighted, bool unnormal)
|
||||
{
|
||||
button->setText(icon);
|
||||
QColor color;
|
||||
bool needDesaturation = true;
|
||||
|
||||
if (highlighted) {
|
||||
if (inverted) {
|
||||
if (unnormal) {
|
||||
color = Theme::blue;
|
||||
needDesaturation = false;
|
||||
} else {
|
||||
|
|
|
@ -47,7 +47,7 @@ public:
|
|||
static void initAwesomeLabel(QLabel *label);
|
||||
static void initAwesomeSmallButton(QPushButton *button);
|
||||
static void initAwesomeMiniButton(QPushButton *button);
|
||||
static void updateAwesomeMiniButton(QPushButton *button, QChar icon, bool highlighted, bool inverted=false);
|
||||
static void updateAwesomeMiniButton(QPushButton *button, QChar icon, bool highlighted, bool unnormal=false);
|
||||
static void initAwesomeToolButton(QPushButton *button);
|
||||
static void initAwesomeToolButtonWithoutFont(QPushButton *button);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue