Add new part attribute: colorImageId
parent
4fb109a583
commit
b0000e7a34
|
@ -1,8 +1,11 @@
|
|||
#include "component_property_widget.h"
|
||||
#include "document.h"
|
||||
#include "float_number_widget.h"
|
||||
#include "image_forever.h"
|
||||
#include "image_preview_widget.h"
|
||||
#include "theme.h"
|
||||
#include <QColorDialog>
|
||||
#include <QFileDialog>
|
||||
#include <QGroupBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPushButton>
|
||||
|
@ -188,29 +191,67 @@ ComponentPropertyWidget::ComponentPropertyWidget(Document* document,
|
|||
cutFaceGroupBox->setLayout(cutFaceLayout);
|
||||
}
|
||||
|
||||
QGroupBox* skinGroupBox = nullptr;
|
||||
QGroupBox* colorImageGroupBox = nullptr;
|
||||
if (nullptr != m_part) {
|
||||
QCheckBox* useImageBox = new QCheckBox();
|
||||
Theme::initCheckbox(useImageBox);
|
||||
useImageBox->setText(tr("Use image"));
|
||||
useImageBox->setChecked(m_part->rounded);
|
||||
ImagePreviewWidget* colorImagePreviewWidget = new ImagePreviewWidget;
|
||||
colorImagePreviewWidget->setFixedSize(Theme::partPreviewImageSize * 2, Theme::partPreviewImageSize * 2);
|
||||
colorImagePreviewWidget->updateImage(m_part->colorImageId.isNull() ? QImage() : *ImageForever::get(m_part->colorImageId));
|
||||
connect(m_document, &Document::partColorImageChanged, this, [=]() {
|
||||
auto part = m_document->findPart(m_partId);
|
||||
if (nullptr == part)
|
||||
return;
|
||||
colorImagePreviewWidget->updateImage(part->colorImageId.isNull() ? QImage() : *ImageForever::get(part->colorImageId));
|
||||
});
|
||||
|
||||
QPushButton* colorImageEraser = new QPushButton(QChar(fa::eraser));
|
||||
Theme::initIconButton(colorImageEraser);
|
||||
|
||||
connect(colorImageEraser, &QPushButton::clicked, [=]() {
|
||||
emit setPartColorImage(m_partId, dust3d::Uuid());
|
||||
emit groupOperationAdded();
|
||||
});
|
||||
|
||||
QPushButton* colorImagePicker = new QPushButton(QChar(fa::image));
|
||||
Theme::initIconButton(colorImagePicker);
|
||||
|
||||
connect(colorImagePicker, &QPushButton::clicked, [=]() {
|
||||
QImage* image = pickImage();
|
||||
if (nullptr == image)
|
||||
return;
|
||||
auto imageId = ImageForever::add(image);
|
||||
delete image;
|
||||
emit setPartColorImage(m_partId, imageId);
|
||||
emit groupOperationAdded();
|
||||
});
|
||||
|
||||
QHBoxLayout* colorImageToolsLayout = new QHBoxLayout;
|
||||
colorImageToolsLayout->addWidget(colorImageEraser);
|
||||
colorImageToolsLayout->addWidget(colorImagePicker);
|
||||
colorImageToolsLayout->addStretch();
|
||||
|
||||
QVBoxLayout* colorImageLayout = new QVBoxLayout;
|
||||
colorImageLayout->addWidget(colorImagePreviewWidget);
|
||||
colorImageLayout->addLayout(colorImageToolsLayout);
|
||||
|
||||
QHBoxLayout* skinLayout = new QHBoxLayout;
|
||||
skinLayout->addLayout(colorImageLayout);
|
||||
skinLayout->addStretch();
|
||||
skinLayout->addWidget(useImageBox);
|
||||
|
||||
skinGroupBox = new QGroupBox(tr("Skin"));
|
||||
skinGroupBox->setLayout(skinLayout);
|
||||
colorImageGroupBox = new QGroupBox(tr("Color"));
|
||||
colorImageGroupBox->setLayout(skinLayout);
|
||||
}
|
||||
|
||||
QHBoxLayout* skinLayout = new QHBoxLayout;
|
||||
if (nullptr != colorImageGroupBox)
|
||||
skinLayout->addWidget(colorImageGroupBox);
|
||||
|
||||
QVBoxLayout* mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(colorLayout);
|
||||
if (nullptr != deformGroupBox)
|
||||
mainLayout->addWidget(deformGroupBox);
|
||||
if (nullptr != cutFaceGroupBox)
|
||||
mainLayout->addWidget(cutFaceGroupBox);
|
||||
if (nullptr != skinGroupBox)
|
||||
mainLayout->addWidget(skinGroupBox);
|
||||
mainLayout->addLayout(skinLayout);
|
||||
mainLayout->setSizeConstraint(QLayout::SetFixedSize);
|
||||
|
||||
connect(this, &ComponentPropertyWidget::setPartColorState, m_document, &Document::setPartColorState);
|
||||
|
@ -223,6 +264,7 @@ ComponentPropertyWidget::ComponentPropertyWidget(Document* document,
|
|||
connect(this, &ComponentPropertyWidget::setPartSubdivState, m_document, &Document::setPartSubdivState);
|
||||
connect(this, &ComponentPropertyWidget::setPartChamferState, m_document, &Document::setPartChamferState);
|
||||
connect(this, &ComponentPropertyWidget::setPartRoundState, m_document, &Document::setPartRoundState);
|
||||
connect(this, &ComponentPropertyWidget::setPartColorImage, m_document, &Document::setPartColorImage);
|
||||
connect(this, &ComponentPropertyWidget::groupOperationAdded, m_document, &Document::saveSnapshot);
|
||||
|
||||
setLayout(mainLayout);
|
||||
|
@ -230,6 +272,19 @@ ComponentPropertyWidget::ComponentPropertyWidget(Document* document,
|
|||
setFixedSize(minimumSizeHint());
|
||||
}
|
||||
|
||||
QImage* ComponentPropertyWidget::pickImage()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this, QString(), QString(),
|
||||
tr("Image Files (*.png *.jpg *.bmp)"))
|
||||
.trimmed();
|
||||
if (fileName.isEmpty())
|
||||
return nullptr;
|
||||
QImage* image = new QImage();
|
||||
if (!image->load(fileName))
|
||||
return nullptr;
|
||||
return image;
|
||||
}
|
||||
|
||||
void ComponentPropertyWidget::preparePartIds()
|
||||
{
|
||||
std::unordered_set<dust3d::Uuid> addedPartIdSet;
|
||||
|
|
|
@ -20,6 +20,7 @@ signals:
|
|||
void setPartChamferState(const dust3d::Uuid& partId, bool chamfered);
|
||||
void setPartRoundState(const dust3d::Uuid& partId, bool rounded);
|
||||
void setPartCutRotation(const dust3d::Uuid& partId, float cutRotation);
|
||||
void setPartColorImage(const dust3d::Uuid& partId, const dust3d::Uuid& imageId);
|
||||
void groupOperationAdded();
|
||||
|
||||
public:
|
||||
|
@ -38,6 +39,7 @@ private:
|
|||
QColor m_color;
|
||||
QColor lastColor();
|
||||
void preparePartIds();
|
||||
QImage* pickImage();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1615,6 +1615,9 @@ void Document::toSnapshot(dust3d::Snapshot* snapshot, const std::set<dust3d::Uui
|
|||
part["cutFace"] = CutFaceToString(partIt.second.cutFace);
|
||||
}
|
||||
}
|
||||
if (!partIt.second.colorImageId.isNull()) {
|
||||
part["colorImageId"] = partIt.second.colorImageId.toString();
|
||||
}
|
||||
part["__dirty"] = partIt.second.dirty ? "true" : "false";
|
||||
if (partIt.second.hasColor)
|
||||
part["color"] = partIt.second.color.name(QColor::HexArgb).toUtf8().constData();
|
||||
|
@ -1857,6 +1860,10 @@ void Document::addFromSnapshot(const dust3d::Snapshot& snapshot, enum SnapshotSo
|
|||
cutFaceLinkedIdModifyMap.insert({ part.id, cutFaceLinkedId });
|
||||
}
|
||||
}
|
||||
const auto& colorImageIt = partKv.second.find("colorImageId");
|
||||
if (colorImageIt != partKv.second.end()) {
|
||||
part.colorImageId = dust3d::Uuid(colorImageIt->second);
|
||||
}
|
||||
if (dust3d::String::isTrue(dust3d::String::valueOrEmpty(partKv.second, "inverse")))
|
||||
inversePartIds.insert(part.id);
|
||||
const auto& colorIt = partKv.second.find("color");
|
||||
|
|
|
@ -32,6 +32,13 @@ void DocumentSaver::process()
|
|||
void DocumentSaver::collectUsedResourceIds(const dust3d::Snapshot* snapshot,
|
||||
std::set<dust3d::Uuid>& imageIds)
|
||||
{
|
||||
for (const auto& part : snapshot->parts) {
|
||||
auto findImageIdString = part.second.find("colorImageId");
|
||||
if (findImageIdString == part.second.end())
|
||||
continue;
|
||||
dust3d::Uuid imageId = dust3d::Uuid(findImageIdString->second);
|
||||
imageIds.insert(imageId);
|
||||
}
|
||||
for (const auto& material : snapshot->materials) {
|
||||
for (auto& layer : material.second) {
|
||||
for (auto& mapItem : layer.second) {
|
||||
|
|
Loading…
Reference in New Issue