diff --git a/languages/dust3d_zh_CN.ts b/languages/dust3d_zh_CN.ts
index 78188e31..31c7fba5 100644
--- a/languages/dust3d_zh_CN.ts
+++ b/languages/dust3d_zh_CN.ts
@@ -606,16 +606,16 @@ Tips:
曲线
-
- 加速:
+
+ 加速
-
- 回弹:
+
+ 减速
-
- 减速:
+
+ 回弹
@@ -807,6 +807,10 @@ Tips:
透明度
+
+
+ 肚白效果
+
PoseEditWidget
diff --git a/src/document.cpp b/src/document.cpp
index 8fee7d76..bffd13e7 100644
--- a/src/document.cpp
+++ b/src/document.cpp
@@ -1081,6 +1081,8 @@ void Document::toSnapshot(Snapshot *snapshot, const std::set &limitNodeId
part["name"] = partIt.second.name;
if (partIt.second.materialAdjusted())
part["materialId"] = partIt.second.materialId.toString();
+ if (partIt.second.countershaded)
+ part["countershaded"] = "true";
snapshot->parts[part["id"]] = part;
}
for (const auto &nodeIt: nodeMap) {
@@ -1386,6 +1388,7 @@ void Document::addFromSnapshot(const Snapshot &snapshot, bool fromPaste)
const auto &materialIdIt = partKv.second.find("materialId");
if (materialIdIt != partKv.second.end())
part.materialId = oldNewIdMap[QUuid(materialIdIt->second)];
+ part.countershaded = isTrueValueString(valueOfKeyInMapOrEmpty(partKv.second, "countershaded"));
newAddedPartIds.insert(part.id);
}
for (const auto &it: cutFaceLinkedIdModifyMap) {
@@ -2744,6 +2747,21 @@ void Document::setPartHollowThickness(QUuid partId, float hollowThickness)
emit skeletonChanged();
}
+void Document::setPartCountershaded(QUuid partId, bool countershaded)
+{
+ auto part = partMap.find(partId);
+ if (part == partMap.end()) {
+ qDebug() << "Part not found:" << partId;
+ return;
+ }
+ if (part->second.countershaded == countershaded)
+ return;
+ part->second.countershaded = countershaded;
+ part->second.dirty = true;
+ emit partCountershadeStateChanged(partId);
+ emit textureChanged();
+}
+
void Document::setPartCutRotation(QUuid partId, float cutRotation)
{
auto part = partMap.find(partId);
diff --git a/src/document.h b/src/document.h
index 07c2c1d3..d9d0f4c7 100644
--- a/src/document.h
+++ b/src/document.h
@@ -434,6 +434,7 @@ signals:
void partTargetChanged(QUuid partId);
void partColorSolubilityChanged(QUuid partId);
void partHollowThicknessChanged(QUuid partId);
+ void partCountershadeStateChanged(QUuid partId);
void componentCombineModeChanged(QUuid componentId);
void cleanup();
void cleanupScript();
@@ -622,6 +623,7 @@ public slots:
void setPartTarget(QUuid partId, PartTarget target);
void setPartColorSolubility(QUuid partId, float solubility);
void setPartHollowThickness(QUuid partId, float hollowThickness);
+ void setPartCountershaded(QUuid partId, bool countershaded);
void setComponentCombineMode(QUuid componentId, CombineMode combineMode);
void moveComponentUp(QUuid componentId);
void moveComponentDown(QUuid componentId);
diff --git a/src/documentwindow.cpp b/src/documentwindow.cpp
index 022acb04..592d88bf 100644
--- a/src/documentwindow.cpp
+++ b/src/documentwindow.cpp
@@ -1018,6 +1018,7 @@ DocumentWindow::DocumentWindow() :
connect(m_document, &Document::partHollowThicknessChanged, partTreeWidget, &PartTreeWidget::partHollowThicknessChanged);
connect(m_document, &Document::partMaterialIdChanged, partTreeWidget, &PartTreeWidget::partMaterialIdChanged);
connect(m_document, &Document::partColorSolubilityChanged, partTreeWidget, &PartTreeWidget::partColorSolubilityChanged);
+ connect(m_document, &Document::partCountershadeStateChanged, partTreeWidget, &PartTreeWidget::partCountershadeStateChanged);
connect(m_document, &Document::partRemoved, partTreeWidget, &PartTreeWidget::partRemoved);
connect(m_document, &Document::cleanup, partTreeWidget, &PartTreeWidget::removeAllContent);
connect(m_document, &Document::partChecked, partTreeWidget, &PartTreeWidget::partChecked);
diff --git a/src/main.cpp b/src/main.cpp
index cc1572fc..e376cb2e 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -40,7 +40,7 @@ int main(int argc, char ** argv)
darkPalette.setColor(QPalette::BrightText, Theme::red);
darkPalette.setColor(QPalette::Link, QColor(42, 130, 218));
darkPalette.setColor(QPalette::Highlight, Theme::red);
- darkPalette.setColor(QPalette::HighlightedText, Theme::black);
+ darkPalette.setColor(QPalette::HighlightedText, Theme::black);
qApp->setPalette(darkPalette);
//qApp->setStyleSheet("QToolTip { color: #ffffff; background-color: #fc6621; border: 1px solid white; }");
diff --git a/src/meshgenerator.cpp b/src/meshgenerator.cpp
index 228f9a86..6ce4294f 100644
--- a/src/meshgenerator.cpp
+++ b/src/meshgenerator.cpp
@@ -587,6 +587,7 @@ nodemesh::Combiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdSt
const auto &originNodeIdString = nodeIndexToIdStringMap[node.originNodeIndex];
OutcomePaintNode paintNode;
+ paintNode.originNodeIndex = node.originNodeIndex;
paintNode.originNodeId = QUuid(originNodeIdString);
paintNode.radius = node.radius;
paintNode.origin = node.position;
@@ -615,6 +616,8 @@ nodemesh::Combiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdSt
paintNode.baseNormal = builder->nodeBaseNormal(i);
paintNode.direction = builder->nodeTraverseDirection(i);
paintNode.order = builder->nodeTraverseOrder(i);
+
+ partCache.outcomeNodes[paintNode.originNodeIndex].direction = paintNode.direction;
}
bool hasMeshError = false;
diff --git a/src/motiontimelinewidget.cpp b/src/motiontimelinewidget.cpp
index 08029495..895334af 100644
--- a/src/motiontimelinewidget.cpp
+++ b/src/motiontimelinewidget.cpp
@@ -193,9 +193,20 @@ void MotionTimelineWidget::showInterpolationSettingPopup(int clipIndex, const QP
QWidget *cubicWidget = new QWidget;
QCheckBox *hasAcceleratingBox = new QCheckBox();
+ hasAcceleratingBox->setText(tr("Accelerating"));
+ Theme::initCheckbox(hasAcceleratingBox);
+
QCheckBox *hasDeceleratingBox = new QCheckBox();
+ hasDeceleratingBox->setText(tr("Decelerating"));
+ Theme::initCheckbox(hasDeceleratingBox);
+
QCheckBox *bouncingBeginBox = new QCheckBox();
+ bouncingBeginBox->setText(tr("Bouncing"));
+ Theme::initCheckbox(bouncingBeginBox);
+
QCheckBox *bouncingEndBox = new QCheckBox();
+ bouncingEndBox->setText(tr("Bouncing"));
+ Theme::initCheckbox(bouncingEndBox);
QStackedWidget *stackedWidget = new QStackedWidget;
stackedWidget->addWidget(linearWidget);
@@ -271,29 +282,13 @@ void MotionTimelineWidget::showInterpolationSettingPopup(int clipIndex, const QP
QVBoxLayout *cubicLayout = new QVBoxLayout;
QHBoxLayout *acceleratingLayout = new QHBoxLayout;
- {
- QFormLayout *formLayout = new QFormLayout;
- formLayout->addRow(tr("Accelerating:"), hasAcceleratingBox);
- acceleratingLayout->addLayout(formLayout);
- }
- {
- QFormLayout *formLayout = new QFormLayout;
- formLayout->addRow(tr("Bouncing:"), bouncingBeginBox);
- acceleratingLayout->addLayout(formLayout);
- }
+ acceleratingLayout->addWidget(hasAcceleratingBox);
+ acceleratingLayout->addWidget(bouncingBeginBox);
cubicLayout->addLayout(acceleratingLayout);
QHBoxLayout *deceleratingLayout = new QHBoxLayout;
- {
- QFormLayout *formLayout = new QFormLayout;
- formLayout->addRow(tr("Decelerating:"), hasDeceleratingBox);
- deceleratingLayout->addLayout(formLayout);
- }
- {
- QFormLayout *formLayout = new QFormLayout;
- formLayout->addRow(tr("Bouncing:"), bouncingEndBox);
- deceleratingLayout->addLayout(formLayout);
- }
+ deceleratingLayout->addWidget(hasDeceleratingBox);
+ deceleratingLayout->addWidget(bouncingEndBox);
cubicLayout->addLayout(deceleratingLayout);
cubicWidget->setLayout(cubicLayout);
diff --git a/src/outcome.h b/src/outcome.h
index 81d15c8b..ec302af1 100644
--- a/src/outcome.h
+++ b/src/outcome.h
@@ -23,10 +23,12 @@ struct OutcomeNode
QUuid mirrorFromPartId;
QUuid mirroredByPartId;
BoneMark boneMark;
+ QVector3D direction;
};
struct OutcomePaintNode
{
+ int originNodeIndex;
QUuid originNodeId;
QVector3D origin;
float radius = 0;
diff --git a/src/parttreewidget.cpp b/src/parttreewidget.cpp
index aa6a7227..95eebcbb 100644
--- a/src/parttreewidget.cpp
+++ b/src/parttreewidget.cpp
@@ -1046,6 +1046,17 @@ void PartTreeWidget::partColorSolubilityChanged(QUuid partId)
widget->updateColorButton();
}
+void PartTreeWidget::partCountershadeStateChanged(QUuid partId)
+{
+ auto item = m_partItemMap.find(partId);
+ if (item == m_partItemMap.end()) {
+ qDebug() << "Part item not found:" << partId;
+ return;
+ }
+ PartWidget *widget = (PartWidget *)itemWidget(item->second, 0);
+ widget->updateColorButton();
+}
+
void PartTreeWidget::partChecked(QUuid partId)
{
auto item = m_partItemMap.find(partId);
diff --git a/src/parttreewidget.h b/src/parttreewidget.h
index e35d0b56..3e89cd56 100644
--- a/src/parttreewidget.h
+++ b/src/parttreewidget.h
@@ -71,6 +71,7 @@ public slots:
void partHollowThicknessChanged(QUuid partId);
void partMaterialIdChanged(QUuid partId);
void partColorSolubilityChanged(QUuid partId);
+ void partCountershadeStateChanged(QUuid partId);
void partChecked(QUuid partId);
void partUnchecked(QUuid partId);
void partComponentChecked(QUuid partId);
diff --git a/src/partwidget.cpp b/src/partwidget.cpp
index 2d63773b..068e4d4d 100644
--- a/src/partwidget.cpp
+++ b/src/partwidget.cpp
@@ -7,6 +7,7 @@
#include
#include
#include
+#include
#include
#include "partwidget.h"
#include "theme.h"
@@ -172,6 +173,7 @@ PartWidget::PartWidget(const Document *document, QUuid partId) :
connect(this, &PartWidget::setPartMaterialId, m_document, &Document::setPartMaterialId);
connect(this, &PartWidget::setPartColorSolubility, m_document, &Document::setPartColorSolubility);
connect(this, &PartWidget::setPartHollowThickness, m_document, &Document::setPartHollowThickness);
+ connect(this, &PartWidget::setPartCountershaded, m_document, &Document::setPartCountershaded);
connect(this, &PartWidget::checkPart, m_document, &Document::checkPart);
connect(this, &PartWidget::enableBackgroundBlur, m_document, &Document::enableBackgroundBlur);
connect(this, &PartWidget::disableBackgroundBlur, m_document, &Document::disableBackgroundBlur);
@@ -361,10 +363,21 @@ void PartWidget::showColorSettingPopup(const QPoint &pos)
palette.setColor(QPalette::Button, choosenColor);
pickButton->setPalette(palette);
+ QCheckBox *countershadeStateBox = new QCheckBox();
+ Theme::initCheckbox(countershadeStateBox);
+ countershadeStateBox->setText(tr("Countershaded"));
+ countershadeStateBox->setChecked(part->countershaded);
+
+ connect(countershadeStateBox, &QCheckBox::stateChanged, this, [=]() {
+ emit setPartCountershaded(m_partId, countershadeStateBox->isChecked());
+ emit groupOperationAdded();
+ });
+
QHBoxLayout *colorLayout = new QHBoxLayout;
colorLayout->addWidget(colorEraser);
colorLayout->addWidget(pickButton);
colorLayout->addStretch();
+ colorLayout->addWidget(countershadeStateBox);
connect(colorEraser, &QPushButton::clicked, [=]() {
emit setPartColorState(m_partId, false, Qt::white);
@@ -894,7 +907,7 @@ void PartWidget::updateColorButton()
qDebug() << "Part not found:" << m_partId;
return;
}
- if (part->hasColor || part->materialAdjusted() || part->colorSolubilityAdjusted())
+ if (part->hasColor || part->materialAdjusted() || part->colorSolubilityAdjusted() || part->countershaded)
updateButton(m_colorButton, QChar(fa::eyedropper), true);
else
updateButton(m_colorButton, QChar(fa::eyedropper), false);
diff --git a/src/partwidget.h b/src/partwidget.h
index 6244ebc8..53c892d6 100644
--- a/src/partwidget.h
+++ b/src/partwidget.h
@@ -29,6 +29,7 @@ signals:
void setPartMaterialId(QUuid partId, QUuid materialId);
void setPartColorSolubility(QUuid partId, float colorSolubility);
void setPartHollowThickness(QUuid partId, float hollowThickness);
+ void setPartCountershaded(QUuid partId, bool countershaded);
void movePartUp(QUuid partId);
void movePartDown(QUuid partId);
void movePartToTop(QUuid partId);
diff --git a/src/preferenceswidget.cpp b/src/preferenceswidget.cpp
index 8db258af..ef023731 100644
--- a/src/preferenceswidget.cpp
+++ b/src/preferenceswidget.cpp
@@ -58,11 +58,13 @@ PreferencesWidget::PreferencesWidget(const Document *document, QWidget *parent)
});
QCheckBox *flatShadingBox = new QCheckBox();
+ Theme::initCheckbox(flatShadingBox);
connect(flatShadingBox, &QCheckBox::stateChanged, this, [=]() {
Preferences::instance().setFlatShading(flatShadingBox->isChecked());
});
QCheckBox *threeNodesBranchEnabledBox = new QCheckBox();
+ Theme::initCheckbox(threeNodesBranchEnabledBox);
connect(threeNodesBranchEnabledBox, &QCheckBox::stateChanged, this, [=]() {
Preferences::instance().setThreeNodesBranchEnableState(threeNodesBranchEnabledBox->isChecked());
});
diff --git a/src/scriptvariableswidget.cpp b/src/scriptvariableswidget.cpp
index b6beffa7..17206de3 100644
--- a/src/scriptvariableswidget.cpp
+++ b/src/scriptvariableswidget.cpp
@@ -87,6 +87,7 @@ void ScriptVariablesWidget::reload()
auto defaultValue = isTrueValueString(valueOfKeyInMapOrEmpty(variable.second, "defaultValue"));
QCheckBox *checkBox = new QCheckBox;
+ Theme::initCheckbox(checkBox);
checkBox->setText(name);
checkBox->setChecked(value);
diff --git a/src/skeletondocument.h b/src/skeletondocument.h
index 3f25094d..c5322c20 100644
--- a/src/skeletondocument.h
+++ b/src/skeletondocument.h
@@ -178,6 +178,7 @@ public:
float deformMapScale;
QUuid deformMapImageId;
float hollowThickness;
+ bool countershaded;
SkeletonPart(const QUuid &withId=QUuid()) :
visible(true),
locked(false),
@@ -198,7 +199,8 @@ public:
target(PartTarget::Model),
colorSolubility(0.0),
deformMapScale(1.0),
- hollowThickness(0.0)
+ hollowThickness(0.0),
+ countershaded(false)
{
id = withId.isNull() ? QUuid::createUuid() : withId;
}
@@ -311,6 +313,7 @@ public:
materialId = other.materialId;
target = other.target;
colorSolubility = other.colorSolubility;
+ countershaded = other.countershaded;
}
void updatePreviewMesh(MeshLoader *previewMesh)
{
diff --git a/src/texturegenerator.cpp b/src/texturegenerator.cpp
index 32b4a150..fb690d01 100644
--- a/src/texturegenerator.cpp
+++ b/src/texturegenerator.cpp
@@ -171,6 +171,8 @@ void TextureGenerator::prepare()
materialId = QUuid(materialIdIt->second);
QUuid partId = QUuid(partIt.first);
updatedMaterialIdMap.insert({partId, materialId});
+ if (isTrueValueString(valueOfKeyInMapOrEmpty(partIt.second, "countershaded")))
+ m_countershadedPartIds.insert(partId);
}
for (const auto &bmeshNode: m_outcome->nodes) {
for (size_t i = 0; i < (int)TextureType::Count - 1; ++i) {
@@ -221,6 +223,7 @@ void TextureGenerator::generate()
const auto &triangleVertexUvs = *m_outcome->triangleVertexUvs();
const auto &triangleSourceNodes = *m_outcome->triangleSourceNodes();
const auto &partUvRects = *m_outcome->partUvRects();
+ const auto &triangleNormals = m_outcome->triangleNormals;
std::map partColorMap;
std::map, const OutcomeNode *> nodeMap;
@@ -382,7 +385,7 @@ void TextureGenerator::generate()
drawTexture(partRoughnessTexturePixmaps, textureRoughnessPainter, false);
drawTexture(partAmbientOcclusionTexturePixmaps, textureAmbientOcclusionPainter, false);
- auto drawGradient = [&](const QUuid &partId, size_t triangleIndex, size_t firstVertexIndex, size_t secondVertexIndex,
+ auto drawBySolubility = [&](const QUuid &partId, size_t triangleIndex, size_t firstVertexIndex, size_t secondVertexIndex,
const QUuid &neighborPartId) {
const std::vector &uv = triangleVertexUvs[triangleIndex];
const auto &allRects = partUvRects.find(partId);
@@ -495,8 +498,110 @@ void TextureGenerator::generate()
const std::pair &oppositeSource = triangleSourceNodes[std::get<0>(opposite->second)];
if (source.first == oppositeSource.first)
continue;
- drawGradient(source.first, std::get<0>(it.second), std::get<1>(it.second), std::get<2>(it.second), oppositeSource.first);
- drawGradient(oppositeSource.first, std::get<0>(opposite->second), std::get<1>(opposite->second), std::get<2>(opposite->second), source.first);
+ drawBySolubility(source.first, std::get<0>(it.second), std::get<1>(it.second), std::get<2>(it.second), oppositeSource.first);
+ drawBySolubility(oppositeSource.first, std::get<0>(opposite->second), std::get<1>(opposite->second), std::get<2>(opposite->second), source.first);
+ }
+
+ // Draw belly white
+ texturePainter.setCompositionMode(QPainter::CompositionMode_SoftLight);
+ for (size_t triangleIndex = 0; triangleIndex < m_outcome->triangles.size(); ++triangleIndex) {
+ const auto &normal = triangleNormals[triangleIndex];
+ const std::pair &source = triangleSourceNodes[triangleIndex];
+ const auto &partId = source.first;
+ if (m_countershadedPartIds.find(partId) == m_countershadedPartIds.end())
+ continue;
+
+ const auto &allRects = partUvRects.find(partId);
+ if (allRects == partUvRects.end()) {
+ qDebug() << "Found part uv rects failed";
+ continue;
+ }
+
+ const auto &findOutcomeNode = nodeMap.find(source);
+ if (findOutcomeNode == nodeMap.end())
+ continue;
+ const OutcomeNode *outcomeNode = findOutcomeNode->second;
+ if (qAbs(QVector3D::dotProduct(outcomeNode->direction, QVector3D(0, 1, 0))) >= 0.707) {
+ if (QVector3D::dotProduct(normal, QVector3D(0, 0, 1)) <= 0.0)
+ continue;
+ } else {
+ if (QVector3D::dotProduct(normal, QVector3D(0, -1, 0)) <= 0.0)
+ continue;
+ }
+
+ const auto &triangleIndices = m_outcome->triangles[triangleIndex];
+ if (triangleIndices.size() != 3) {
+ qDebug() << "Found invalid triangle indices";
+ continue;
+ }
+
+ const std::vector &uv = triangleVertexUvs[triangleIndex];
+ QVector2D middlePoint = (uv[0] + uv[1] + uv[2]) / 3.0;
+ float finalRadius = (uv[0].distanceToPoint(uv[1]) +
+ uv[1].distanceToPoint(uv[2]) +
+ uv[2].distanceToPoint(uv[0])) / 3.0;
+ QRadialGradient gradient(QPointF(middlePoint.x() * TextureGenerator::m_textureSize,
+ middlePoint.y() * TextureGenerator::m_textureSize),
+ finalRadius * TextureGenerator::m_textureSize);
+ gradient.setColorAt(0.0, Qt::white);
+ gradient.setColorAt(1.0, Qt::transparent);
+ for (const auto &it: allRects->second) {
+ if (it.contains(middlePoint.x(), middlePoint.y())) {
+ QRectF fillTarget((middlePoint.x() - finalRadius),
+ (middlePoint.y() - finalRadius),
+ (finalRadius + finalRadius),
+ (finalRadius + finalRadius));
+ auto clippedRect = it.intersected(fillTarget);
+ QRectF translatedRect = {
+ clippedRect.left() * TextureGenerator::m_textureSize,
+ clippedRect.top() * TextureGenerator::m_textureSize,
+ clippedRect.width() * TextureGenerator::m_textureSize,
+ clippedRect.height() * TextureGenerator::m_textureSize
+ };
+ texturePainter.fillRect(translatedRect, gradient);
+ }
+ }
+
+ // Fill the neighbor halfedges
+ for (int i = 0; i < 3; ++i) {
+ int j = (i + 1) % 3;
+ auto oppositeHalfEdge = std::make_pair(triangleIndices[j], triangleIndices[i]);
+ const auto &opposite = halfEdgeToTriangleMap.find(oppositeHalfEdge);
+ if (opposite == halfEdgeToTriangleMap.end())
+ continue;
+ auto oppositeTriangleIndex = std::get<0>(opposite->second);
+ const std::pair &oppositeSource = triangleSourceNodes[oppositeTriangleIndex];
+ if (partId == oppositeSource.first)
+ continue;
+ const auto &oppositeAllRects = partUvRects.find(oppositeSource.first);
+ if (oppositeAllRects == partUvRects.end()) {
+ qDebug() << "Found part uv rects failed";
+ continue;
+ }
+ const std::vector &oppositeUv = triangleVertexUvs[oppositeTriangleIndex];
+ QVector2D oppositeMiddlePoint = (oppositeUv[std::get<1>(opposite->second)] + oppositeUv[std::get<2>(opposite->second)]) * 0.5;
+ QRadialGradient oppositeGradient(QPointF(oppositeMiddlePoint.x() * TextureGenerator::m_textureSize,
+ oppositeMiddlePoint.y() * TextureGenerator::m_textureSize),
+ finalRadius * TextureGenerator::m_textureSize);
+ oppositeGradient.setColorAt(0.0, Qt::white);
+ oppositeGradient.setColorAt(1.0, Qt::transparent);
+ for (const auto &it: oppositeAllRects->second) {
+ if (it.contains(oppositeMiddlePoint.x(), oppositeMiddlePoint.y())) {
+ QRectF fillTarget((oppositeMiddlePoint.x() - finalRadius),
+ (oppositeMiddlePoint.y() - finalRadius),
+ (finalRadius + finalRadius),
+ (finalRadius + finalRadius));
+ auto clippedRect = it.intersected(fillTarget);
+ QRectF translatedRect = {
+ clippedRect.left() * TextureGenerator::m_textureSize,
+ clippedRect.top() * TextureGenerator::m_textureSize,
+ clippedRect.width() * TextureGenerator::m_textureSize,
+ clippedRect.height() * TextureGenerator::m_textureSize
+ };
+ texturePainter.fillRect(translatedRect, oppositeGradient);
+ }
+ }
+ }
}
hasNormalMap = !m_partNormalTextureMap.empty();
diff --git a/src/texturegenerator.h b/src/texturegenerator.h
index 61689798..09498b51 100644
--- a/src/texturegenerator.h
+++ b/src/texturegenerator.h
@@ -58,6 +58,7 @@ private:
std::map> m_partMetalnessTextureMap;
std::map> m_partRoughnessTextureMap;
std::map> m_partAmbientOcclusionTextureMap;
+ std::set m_countershadedPartIds;
Snapshot *m_snapshot;
};
diff --git a/src/theme.cpp b/src/theme.cpp
index ce8f131f..919d7193 100644
--- a/src/theme.cpp
+++ b/src/theme.cpp
@@ -177,6 +177,13 @@ void Theme::initToolButton(QPushButton *button)
button->setFocusPolicy(Qt::NoFocus);
}
+void Theme::initCheckbox(QCheckBox *checkbox)
+{
+ QPalette palette = checkbox->palette();
+ palette.setColor(QPalette::Background, Theme::white);
+ checkbox->setPalette(palette);
+}
+
QWidget *Theme::createHorizontalLineWidget()
{
QWidget *hrLightWidget = new QWidget;
diff --git a/src/theme.h b/src/theme.h
index 49ff4733..5a049fd1 100644
--- a/src/theme.h
+++ b/src/theme.h
@@ -5,6 +5,7 @@
#include