Apply webkit style clang format on code base

master
Jeremy HU 2022-10-18 20:35:04 +11:00
parent 73f0404c2e
commit 57b1a802f3
213 changed files with 7933 additions and 8534 deletions

View File

@ -1,22 +1,22 @@
#include <QOpenGLFunctions>
#include <QTextEdit> #include <QTextEdit>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QOpenGLFunctions>
#include "about_widget.h" #include "about_widget.h"
#include "version.h"
#include "model_widget.h" #include "model_widget.h"
#include "version.h"
AboutWidget::AboutWidget() AboutWidget::AboutWidget()
{ {
QTextEdit *versionInfoLabel = new QTextEdit; QTextEdit* versionInfoLabel = new QTextEdit;
versionInfoLabel->setText(QString("%1 %2 (version: %3 build: %4 %5)\nopengl: %6 shader: %7 core: %8").arg(APP_NAME).arg(APP_HUMAN_VER).arg(APP_VER).arg(__DATE__).arg(__TIME__).arg(ModelWidget::m_openGLVersion).arg(ModelWidget::m_openGLShadingLanguageVersion).arg(ModelWidget::m_openGLIsCoreProfile ? "true" : "false")); versionInfoLabel->setText(QString("%1 %2 (version: %3 build: %4 %5)\nopengl: %6 shader: %7 core: %8").arg(APP_NAME).arg(APP_HUMAN_VER).arg(APP_VER).arg(__DATE__).arg(__TIME__).arg(ModelWidget::m_openGLVersion).arg(ModelWidget::m_openGLShadingLanguageVersion).arg(ModelWidget::m_openGLIsCoreProfile ? "true" : "false"));
versionInfoLabel->setReadOnly(true); versionInfoLabel->setReadOnly(true);
QVBoxLayout *mainLayout = new QVBoxLayout; QVBoxLayout* mainLayout = new QVBoxLayout;
mainLayout->addWidget(versionInfoLabel); mainLayout->addWidget(versionInfoLabel);
setLayout(mainLayout); setLayout(mainLayout);
setFixedSize(QSize(350, 100)); setFixedSize(QSize(350, 100));
setWindowTitle(applicationTitle(tr("About"))); setWindowTitle(applicationTitle(tr("About")));
} }

View File

@ -3,8 +3,7 @@
#include <QDialog> #include <QDialog>
class AboutWidget : public QDialog class AboutWidget : public QDialog {
{
Q_OBJECT Q_OBJECT
public: public:
AboutWidget(); AboutWidget();

View File

@ -1,9 +1,9 @@
#include <QtGlobal>
#include <QMatrix4x4>
#include <QDebug>
#include <cmath>
#include <QtMath>
#include "ccd_ik_resolver.h" #include "ccd_ik_resolver.h"
#include <QDebug>
#include <QMatrix4x4>
#include <QtGlobal>
#include <QtMath>
#include <cmath>
CcdIkSolver::CcdIkSolver() CcdIkSolver::CcdIkSolver()
{ {
@ -15,9 +15,9 @@ void CcdIkSolver::setSolveFrom(int fromNodeIndex)
} }
void CcdIkSolver::setNodeHingeConstraint(int nodeIndex, void CcdIkSolver::setNodeHingeConstraint(int nodeIndex,
const QVector3D &axis, double minLimitDegrees, double maxLimitDegrees) const QVector3D& axis, double minLimitDegrees, double maxLimitDegrees)
{ {
auto &node = m_nodes[nodeIndex]; auto& node = m_nodes[nodeIndex];
node.axis = axis; node.axis = axis;
node.minLimitDegrees = minLimitDegrees; node.minLimitDegrees = minLimitDegrees;
node.maxLimitDegrees = maxLimitDegrees; node.maxLimitDegrees = maxLimitDegrees;
@ -33,7 +33,7 @@ void CcdIkSolver::setDistanceThreshod(float threshold)
m_distanceThreshold2 = threshold * threshold; m_distanceThreshold2 = threshold * threshold;
} }
int CcdIkSolver::addNodeInOrder(const QVector3D &position) int CcdIkSolver::addNodeInOrder(const QVector3D& position)
{ {
CcdIkNode node; CcdIkNode node;
node.position = position; node.position = position;
@ -42,13 +42,13 @@ int CcdIkSolver::addNodeInOrder(const QVector3D &position)
return nodeCount; return nodeCount;
} }
void CcdIkSolver::solveTo(const QVector3D &position) void CcdIkSolver::solveTo(const QVector3D& position)
{ {
//qDebug() << "solveTo:" << position; //qDebug() << "solveTo:" << position;
m_destination = position; m_destination = position;
float lastDistance2 = 0; float lastDistance2 = 0;
for (int i = 0; i < m_maxRound; i++) { for (int i = 0; i < m_maxRound; i++) {
const auto &endEffector = m_nodes[m_nodes.size() - 1]; const auto& endEffector = m_nodes[m_nodes.size() - 1];
float distance2 = (endEffector.position - m_destination).lengthSquared(); float distance2 = (endEffector.position - m_destination).lengthSquared();
//qDebug() << "Round:" << i << " distance2:" << distance2; //qDebug() << "Round:" << i << " distance2:" << distance2;
if (distance2 <= m_distanceThreshold2) if (distance2 <= m_distanceThreshold2)
@ -60,7 +60,7 @@ void CcdIkSolver::solveTo(const QVector3D &position)
} }
} }
const QVector3D &CcdIkSolver::getNodeSolvedPosition(int index) const QVector3D& CcdIkSolver::getNodeSolvedPosition(int index)
{ {
Q_ASSERT(index >= 0 && index < (int)m_nodes.size()); Q_ASSERT(index >= 0 && index < (int)m_nodes.size());
return m_nodes[index].position; return m_nodes[index].position;
@ -82,18 +82,18 @@ float CcdIkSolver::angleInRangle360BetweenTwoVectors(QVector3D a, QVector3D b, Q
void CcdIkSolver::iterate() void CcdIkSolver::iterate()
{ {
auto rotateChildren = [&](const QQuaternion &quaternion, int i) { auto rotateChildren = [&](const QQuaternion& quaternion, int i) {
const auto &origin = m_nodes[i]; const auto& origin = m_nodes[i];
for (size_t j = i + 1; j <= m_nodes.size() - 1; j++) { for (size_t j = i + 1; j <= m_nodes.size() - 1; j++) {
auto &next = m_nodes[j]; auto& next = m_nodes[j];
const auto offset = next.position - origin.position; const auto offset = next.position - origin.position;
next.position = origin.position + quaternion.rotatedVector(offset); next.position = origin.position + quaternion.rotatedVector(offset);
} }
}; };
for (int i = m_nodes.size() - 2; i >= m_fromNodeIndex; i--) { for (int i = m_nodes.size() - 2; i >= m_fromNodeIndex; i--) {
const auto &origin = m_nodes[i]; const auto& origin = m_nodes[i];
const auto &endEffector = m_nodes[m_nodes.size() - 1]; const auto& endEffector = m_nodes[m_nodes.size() - 1];
QVector3D from = (endEffector.position - origin.position).normalized(); QVector3D from = (endEffector.position - origin.position).normalized();
QVector3D to = (m_destination - origin.position).normalized(); QVector3D to = (m_destination - origin.position).normalized();
auto quaternion = QQuaternion::rotationTo(from, to); auto quaternion = QQuaternion::rotationTo(from, to);
@ -111,12 +111,10 @@ void CcdIkSolver::iterate()
int childIndex = i + 1; int childIndex = i + 1;
if (childIndex >= m_nodes.size()) if (childIndex >= m_nodes.size())
continue; continue;
const auto &parent = m_nodes[parentIndex]; const auto& parent = m_nodes[parentIndex];
const auto &child = m_nodes[childIndex]; const auto& child = m_nodes[childIndex];
QVector3D angleFrom = (QVector3D(0.0, parent.position.y(), parent.position.z()) - QVector3D angleFrom = (QVector3D(0.0, parent.position.y(), parent.position.z()) - QVector3D(0.0, origin.position.y(), origin.position.z())).normalized();
QVector3D(0.0, origin.position.y(), origin.position.z())).normalized(); QVector3D angleTo = (QVector3D(0.0, child.position.y(), child.position.z()) - QVector3D(0.0, origin.position.y(), origin.position.z())).normalized();
QVector3D angleTo = (QVector3D(0.0, child.position.y(), child.position.z()) -
QVector3D(0.0, origin.position.y(), origin.position.z())).normalized();
float degrees = angleInRangle360BetweenTwoVectors(angleFrom, angleTo, QVector3D(1.0, 0.0, 0.0)); float degrees = angleInRangle360BetweenTwoVectors(angleFrom, angleTo, QVector3D(1.0, 0.0, 0.0));
if (degrees < origin.minLimitDegrees) { if (degrees < origin.minLimitDegrees) {
auto quaternion = QQuaternion::fromAxisAndAngle(QVector3D(1.0, 0.0, 0.0), origin.minLimitDegrees - degrees); auto quaternion = QQuaternion::fromAxisAndAngle(QVector3D(1.0, 0.0, 0.0), origin.minLimitDegrees - degrees);

View File

@ -1,31 +1,30 @@
#ifndef DUST3D_APPLICATION_CCD_IK_SOLVER_H_ #ifndef DUST3D_APPLICATION_CCD_IK_SOLVER_H_
#define DUST3D_APPLICATION_CCD_IK_SOLVER_H_ #define DUST3D_APPLICATION_CCD_IK_SOLVER_H_
#include <vector>
#include <QVector3D>
#include <QQuaternion> #include <QQuaternion>
#include <QVector3D>
#include <vector>
struct CcdIkNode struct CcdIkNode {
{
QVector3D position; QVector3D position;
QVector3D axis; QVector3D axis;
double minLimitDegrees; double minLimitDegrees;
double maxLimitDegrees; double maxLimitDegrees;
}; };
class CcdIkSolver class CcdIkSolver {
{
public: public:
CcdIkSolver(); CcdIkSolver();
void setMaxRound(int maxRound); void setMaxRound(int maxRound);
void setDistanceThreshod(float threshold); void setDistanceThreshod(float threshold);
int addNodeInOrder(const QVector3D &position); int addNodeInOrder(const QVector3D& position);
void solveTo(const QVector3D &position); void solveTo(const QVector3D& position);
const QVector3D &getNodeSolvedPosition(int index); const QVector3D& getNodeSolvedPosition(int index);
int getNodeCount(); int getNodeCount();
void setNodeHingeConstraint(int nodeIndex, void setNodeHingeConstraint(int nodeIndex,
const QVector3D &axis, double minLimitDegrees, double maxLimitDegrees); const QVector3D& axis, double minLimitDegrees, double maxLimitDegrees);
void setSolveFrom(int fromNodeIndex); void setSolveFrom(int fromNodeIndex);
private: private:
float angleInRangle360BetweenTwoVectors(QVector3D a, QVector3D b, QVector3D planeNormal); float angleInRangle360BetweenTwoVectors(QVector3D a, QVector3D b, QVector3D planeNormal);
void iterate(); void iterate();

View File

@ -1,13 +1,13 @@
#include <QAbstractListModel>
#include <dust3d/base/debug.h>
#include "component_list_model.h" #include "component_list_model.h"
#include "document.h" #include "document.h"
#include <QAbstractListModel>
#include <dust3d/base/debug.h>
ComponentListModel::ComponentListModel(const Document *document, QObject *parent): ComponentListModel::ComponentListModel(const Document* document, QObject* parent)
QAbstractListModel(parent), : QAbstractListModel(parent)
m_document(document) , m_document(document)
{ {
connect(m_document, &Document::componentPreviewPixmapChanged, [this](const dust3d::Uuid &componentId) { connect(m_document, &Document::componentPreviewPixmapChanged, [this](const dust3d::Uuid& componentId) {
auto findIndex = this->m_componentIdToIndexMap.find(componentId); auto findIndex = this->m_componentIdToIndexMap.find(componentId);
if (findIndex != this->m_componentIdToIndexMap.end()) { if (findIndex != this->m_componentIdToIndexMap.end()) {
//dust3dDebug << "dataChanged:" << findIndex->second.row(); //dust3dDebug << "dataChanged:" << findIndex->second.row();
@ -18,7 +18,7 @@ ComponentListModel::ComponentListModel(const Document *document, QObject *parent
this->setListingComponentId(dust3d::Uuid()); this->setListingComponentId(dust3d::Uuid());
this->reload(); this->reload();
}); });
connect(m_document, &Document::componentChildrenChanged, [this](const dust3d::Uuid &componentId) { connect(m_document, &Document::componentChildrenChanged, [this](const dust3d::Uuid& componentId) {
if (componentId != this->listingComponentId()) if (componentId != this->listingComponentId())
return; return;
this->reload(); this->reload();
@ -29,7 +29,7 @@ void ComponentListModel::reload()
{ {
beginResetModel(); beginResetModel();
m_componentIdToIndexMap.clear(); m_componentIdToIndexMap.clear();
const SkeletonComponent *listingComponent = m_document->findComponent(m_listingComponentId); const SkeletonComponent* listingComponent = m_document->findComponent(m_listingComponentId);
if (nullptr != listingComponent) { if (nullptr != listingComponent) {
for (int i = 0; i < (int)listingComponent->childrenIds.size(); ++i) { for (int i = 0; i < (int)listingComponent->childrenIds.size(); ++i) {
m_componentIdToIndexMap[listingComponent->childrenIds[i]] = createIndex(i, 0); m_componentIdToIndexMap[listingComponent->childrenIds[i]] = createIndex(i, 0);
@ -39,7 +39,7 @@ void ComponentListModel::reload()
emit layoutChanged(); emit layoutChanged();
} }
QModelIndex ComponentListModel::componentIdToIndex(const dust3d::Uuid &componentId) const QModelIndex ComponentListModel::componentIdToIndex(const dust3d::Uuid& componentId) const
{ {
auto findIndex = m_componentIdToIndexMap.find(componentId); auto findIndex = m_componentIdToIndexMap.find(componentId);
if (findIndex == m_componentIdToIndexMap.end()) if (findIndex == m_componentIdToIndexMap.end())
@ -47,34 +47,34 @@ QModelIndex ComponentListModel::componentIdToIndex(const dust3d::Uuid &component
return findIndex->second; return findIndex->second;
} }
int ComponentListModel::rowCount(const QModelIndex &parent) const int ComponentListModel::rowCount(const QModelIndex& parent) const
{ {
if (parent.isValid()) if (parent.isValid())
return 0; return 0;
const SkeletonComponent *listingComponent = m_document->findComponent(m_listingComponentId); const SkeletonComponent* listingComponent = m_document->findComponent(m_listingComponentId);
if (nullptr == listingComponent) if (nullptr == listingComponent)
return 0; return 0;
return (int)listingComponent->childrenIds.size(); return (int)listingComponent->childrenIds.size();
} }
int ComponentListModel::columnCount(const QModelIndex &parent) const int ComponentListModel::columnCount(const QModelIndex& parent) const
{ {
if (parent.isValid()) if (parent.isValid())
return 0; return 0;
return 1; return 1;
} }
const SkeletonComponent *ComponentListModel::modelIndexToComponent(const QModelIndex &index) const const SkeletonComponent* ComponentListModel::modelIndexToComponent(const QModelIndex& index) const
{ {
const SkeletonComponent *listingComponent = m_document->findComponent(m_listingComponentId); const SkeletonComponent* listingComponent = m_document->findComponent(m_listingComponentId);
if (nullptr == listingComponent) if (nullptr == listingComponent)
return nullptr; return nullptr;
if (index.row() >= (int)listingComponent->childrenIds.size()) { if (index.row() >= (int)listingComponent->childrenIds.size()) {
dust3dDebug << "Component list row is out of range, size:" << listingComponent->childrenIds.size() << "row:" << index.row(); dust3dDebug << "Component list row is out of range, size:" << listingComponent->childrenIds.size() << "row:" << index.row();
return nullptr; return nullptr;
} }
const auto &componentId = listingComponent->childrenIds[index.row()]; const auto& componentId = listingComponent->childrenIds[index.row()];
const SkeletonComponent *component = m_document->findComponent(componentId); const SkeletonComponent* component = m_document->findComponent(componentId);
if (nullptr == component) { if (nullptr == component) {
dust3dDebug << "Component not found:" << componentId.toString(); dust3dDebug << "Component not found:" << componentId.toString();
return nullptr; return nullptr;
@ -82,50 +82,48 @@ const SkeletonComponent *ComponentListModel::modelIndexToComponent(const QModelI
return component; return component;
} }
const dust3d::Uuid ComponentListModel::modelIndexToComponentId(const QModelIndex &index) const const dust3d::Uuid ComponentListModel::modelIndexToComponentId(const QModelIndex& index) const
{ {
const SkeletonComponent *listingComponent = m_document->findComponent(m_listingComponentId); const SkeletonComponent* listingComponent = m_document->findComponent(m_listingComponentId);
if (nullptr == listingComponent) if (nullptr == listingComponent)
return dust3d::Uuid(); return dust3d::Uuid();
if (index.row() >= (int)listingComponent->childrenIds.size()) { if (index.row() >= (int)listingComponent->childrenIds.size()) {
dust3dDebug << "Component list row is out of range, size:" << listingComponent->childrenIds.size() << "row:" << index.row(); dust3dDebug << "Component list row is out of range, size:" << listingComponent->childrenIds.size() << "row:" << index.row();
return dust3d::Uuid(); return dust3d::Uuid();
} }
const auto &componentId = listingComponent->childrenIds[index.row()]; const auto& componentId = listingComponent->childrenIds[index.row()];
return componentId; return componentId;
} }
QVariant ComponentListModel::data(const QModelIndex &index, int role) const QVariant ComponentListModel::data(const QModelIndex& index, int role) const
{ {
switch (role) { switch (role) {
case Qt::ToolTipRole: { case Qt::ToolTipRole: {
const SkeletonComponent *component = modelIndexToComponent(index); const SkeletonComponent* component = modelIndexToComponent(index);
if (nullptr != component) { if (nullptr != component) {
return component->name; return component->name;
}
} }
break; } break;
case Qt::DecorationRole: { case Qt::DecorationRole: {
const SkeletonComponent *component = modelIndexToComponent(index); const SkeletonComponent* component = modelIndexToComponent(index);
if (nullptr != component) { if (nullptr != component) {
if (0 == component->previewPixmap.width()) { if (0 == component->previewPixmap.width()) {
static QPixmap s_emptyPixmap; static QPixmap s_emptyPixmap;
if (0 == s_emptyPixmap.width()) { if (0 == s_emptyPixmap.width()) {
QImage image((int)Theme::partPreviewImageSize, (int)Theme::partPreviewImageSize, QImage::Format_ARGB32); QImage image((int)Theme::partPreviewImageSize, (int)Theme::partPreviewImageSize, QImage::Format_ARGB32);
image.fill(Qt::transparent); image.fill(Qt::transparent);
s_emptyPixmap = QPixmap::fromImage(image); s_emptyPixmap = QPixmap::fromImage(image);
}
return s_emptyPixmap;
} }
return component->previewPixmap; return s_emptyPixmap;
} }
return component->previewPixmap;
} }
break; } break;
} }
return QVariant(); return QVariant();
} }
void ComponentListModel::setListingComponentId(const dust3d::Uuid &componentId) void ComponentListModel::setListingComponentId(const dust3d::Uuid& componentId)
{ {
if (m_listingComponentId == componentId) if (m_listingComponentId == componentId)
return; return;

View File

@ -1,32 +1,33 @@
#ifndef DUST3D_APPLICATION_COMPONENT_LIST_MODEL_H_ #ifndef DUST3D_APPLICATION_COMPONENT_LIST_MODEL_H_
#define DUST3D_APPLICATION_COMPONENT_LIST_MODEL_H_ #define DUST3D_APPLICATION_COMPONENT_LIST_MODEL_H_
#include <unordered_map>
#include <dust3d/base/uuid.h>
#include <QAbstractListModel> #include <QAbstractListModel>
#include <dust3d/base/uuid.h>
#include <unordered_map>
class Document; class Document;
class SkeletonComponent; class SkeletonComponent;
class ComponentListModel: public QAbstractListModel class ComponentListModel : public QAbstractListModel {
{
Q_OBJECT Q_OBJECT
signals: signals:
void listingComponentChanged(const dust3d::Uuid &componentId); void listingComponentChanged(const dust3d::Uuid& componentId);
public: public:
ComponentListModel(const Document *document, QObject *parent=nullptr); ComponentListModel(const Document* document, QObject* parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const; int rowCount(const QModelIndex& parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex& parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role) const; QVariant data(const QModelIndex& index, int role) const;
const SkeletonComponent *modelIndexToComponent(const QModelIndex &index) const; const SkeletonComponent* modelIndexToComponent(const QModelIndex& index) const;
QModelIndex componentIdToIndex(const dust3d::Uuid &componentId) const; QModelIndex componentIdToIndex(const dust3d::Uuid& componentId) const;
const dust3d::Uuid modelIndexToComponentId(const QModelIndex &index) const; const dust3d::Uuid modelIndexToComponentId(const QModelIndex& index) const;
const dust3d::Uuid listingComponentId() const; const dust3d::Uuid listingComponentId() const;
public slots: public slots:
void setListingComponentId(const dust3d::Uuid &componentId); void setListingComponentId(const dust3d::Uuid& componentId);
void reload(); void reload();
private: private:
const Document *m_document = nullptr; const Document* m_document = nullptr;
dust3d::Uuid m_listingComponentId; dust3d::Uuid m_listingComponentId;
std::unordered_map<dust3d::Uuid, QModelIndex> m_componentIdToIndexMap; std::unordered_map<dust3d::Uuid, QModelIndex> m_componentIdToIndexMap;
}; };

View File

@ -1,23 +1,23 @@
#include <memory>
#include "component_preview_grid_widget.h" #include "component_preview_grid_widget.h"
#include "component_list_model.h" #include "component_list_model.h"
#include "document.h" #include "document.h"
#include <memory>
ComponentPreviewGridWidget::ComponentPreviewGridWidget(Document *document, QWidget *parent): ComponentPreviewGridWidget::ComponentPreviewGridWidget(Document* document, QWidget* parent)
PreviewGridView(parent), : PreviewGridView(parent)
m_document(document) , m_document(document)
{ {
m_componentListModel = std::make_unique<ComponentListModel>(m_document); m_componentListModel = std::make_unique<ComponentListModel>(m_document);
setModel(m_componentListModel.get()); setModel(m_componentListModel.get());
connect(this, &ComponentPreviewGridWidget::doubleClicked, [this](const QModelIndex &index) { connect(this, &ComponentPreviewGridWidget::doubleClicked, [this](const QModelIndex& index) {
const SkeletonComponent *component = this->componentListModel()->modelIndexToComponent(index); const SkeletonComponent* component = this->componentListModel()->modelIndexToComponent(index);
if (nullptr == component) if (nullptr == component)
return; return;
if (component->childrenIds.empty()) { if (component->childrenIds.empty()) {
std::vector<dust3d::Uuid> partIds; std::vector<dust3d::Uuid> partIds;
this->m_document->collectComponentDescendantParts(component->id, partIds); this->m_document->collectComponentDescendantParts(component->id, partIds);
for (const auto &partId: partIds) for (const auto& partId : partIds)
emit this->selectPartOnCanvas(partId); emit this->selectPartOnCanvas(partId);
} else { } else {
this->componentListModel()->setListingComponentId(component->id); this->componentListModel()->setListingComponentId(component->id);
@ -25,17 +25,17 @@ ComponentPreviewGridWidget::ComponentPreviewGridWidget(Document *document, QWidg
}); });
} }
ComponentListModel *ComponentPreviewGridWidget::componentListModel() ComponentListModel* ComponentPreviewGridWidget::componentListModel()
{ {
return m_componentListModel.get(); return m_componentListModel.get();
} }
std::vector<const SkeletonComponent *> ComponentPreviewGridWidget::getSelectedComponents() const std::vector<const SkeletonComponent*> ComponentPreviewGridWidget::getSelectedComponents() const
{ {
std::vector<const SkeletonComponent *> components; std::vector<const SkeletonComponent*> components;
QModelIndexList selected = selectionModel()->selectedIndexes(); QModelIndexList selected = selectionModel()->selectedIndexes();
for (const auto &it: selected) { for (const auto& it : selected) {
const auto &component = m_componentListModel->modelIndexToComponent(it); const auto& component = m_componentListModel->modelIndexToComponent(it);
if (nullptr == component) if (nullptr == component)
continue; continue;
components.push_back(component); components.push_back(component);
@ -47,8 +47,8 @@ std::vector<dust3d::Uuid> ComponentPreviewGridWidget::getSelectedComponentIds()
{ {
std::vector<dust3d::Uuid> componentIds; std::vector<dust3d::Uuid> componentIds;
QModelIndexList selected = selectionModel()->selectedIndexes(); QModelIndexList selected = selectionModel()->selectedIndexes();
for (const auto &it: selected) { for (const auto& it : selected) {
const auto &componentId = m_componentListModel->modelIndexToComponentId(it); const auto& componentId = m_componentListModel->modelIndexToComponentId(it);
if (componentId.isNull()) if (componentId.isNull())
continue; continue;
componentIds.push_back(componentId); componentIds.push_back(componentId);
@ -60,7 +60,7 @@ std::vector<dust3d::Uuid> ComponentPreviewGridWidget::getSelectedPartIds() const
{ {
auto selectedComponents = getSelectedComponents(); auto selectedComponents = getSelectedComponents();
std::vector<dust3d::Uuid> partIds; std::vector<dust3d::Uuid> partIds;
for (const auto &component: selectedComponents) { for (const auto& component : selectedComponents) {
if (component->linkToPartId.isNull()) if (component->linkToPartId.isNull())
continue; continue;
partIds.push_back(component->linkToPartId); partIds.push_back(component->linkToPartId);

View File

@ -1,30 +1,31 @@
#ifndef DUST3D_APPLICATION_COMPONENT_PREVIEW_GRID_WIDGET_H_ #ifndef DUST3D_APPLICATION_COMPONENT_PREVIEW_GRID_WIDGET_H_
#define DUST3D_APPLICATION_COMPONENT_PREVIEW_GRID_WIDGET_H_ #define DUST3D_APPLICATION_COMPONENT_PREVIEW_GRID_WIDGET_H_
#include <memory>
#include <dust3d/base/uuid.h>
#include <QAbstractListModel>
#include "preview_grid_view.h"
#include "component_list_model.h" #include "component_list_model.h"
#include "preview_grid_view.h"
#include <QAbstractListModel>
#include <dust3d/base/uuid.h>
#include <memory>
class Document; class Document;
class SkeletonComponent; class SkeletonComponent;
class ComponentPreviewGridWidget: public PreviewGridView class ComponentPreviewGridWidget : public PreviewGridView {
{
Q_OBJECT Q_OBJECT
signals: signals:
void unselectAllOnCanvas(); void unselectAllOnCanvas();
void selectPartOnCanvas(const dust3d::Uuid &partId); void selectPartOnCanvas(const dust3d::Uuid& partId);
public: public:
ComponentPreviewGridWidget(Document *document, QWidget *parent=nullptr); ComponentPreviewGridWidget(Document* document, QWidget* parent = nullptr);
ComponentListModel *componentListModel(); ComponentListModel* componentListModel();
std::vector<const SkeletonComponent *> getSelectedComponents() const; std::vector<const SkeletonComponent*> getSelectedComponents() const;
std::vector<dust3d::Uuid> getSelectedComponentIds() const; std::vector<dust3d::Uuid> getSelectedComponentIds() const;
std::vector<dust3d::Uuid> getSelectedPartIds() const; std::vector<dust3d::Uuid> getSelectedPartIds() const;
private: private:
std::unique_ptr<ComponentListModel> m_componentListModel; std::unique_ptr<ComponentListModel> m_componentListModel;
Document *m_document = nullptr; Document* m_document = nullptr;
}; };
#endif #endif

View File

@ -1,7 +1,7 @@
#include <dust3d/base/debug.h>
#include <QPainter>
#include "theme.h"
#include "component_preview_images_decorator.h" #include "component_preview_images_decorator.h"
#include "theme.h"
#include <QPainter>
#include <dust3d/base/debug.h>
ComponentPreviewImagesDecorator::ComponentPreviewImagesDecorator(std::unique_ptr<std::vector<PreviewInput>> previewInputs) ComponentPreviewImagesDecorator::ComponentPreviewImagesDecorator(std::unique_ptr<std::vector<PreviewInput>> previewInputs)
{ {
@ -21,7 +21,7 @@ void ComponentPreviewImagesDecorator::decorate()
m_resultImages = std::make_unique<std::unordered_map<dust3d::Uuid, std::unique_ptr<QImage>>>(); m_resultImages = std::make_unique<std::unordered_map<dust3d::Uuid, std::unique_ptr<QImage>>>();
QPointF iconOffset(Theme::previewIconMargin, 0); QPointF iconOffset(Theme::previewIconMargin, 0);
for (auto &it: *m_previewInputs) { for (auto& it : *m_previewInputs) {
if (it.isDirectory) { if (it.isDirectory) {
QPainter painter(it.image.get()); QPainter painter(it.image.get());
painter.setRenderHints(QPainter::Antialiasing); painter.setRenderHints(QPainter::Antialiasing);

View File

@ -1,17 +1,15 @@
#ifndef DUST3D_APPLICATION_COMPONENT_PREVIEW_IMAGES_DECORATOR_H_ #ifndef DUST3D_APPLICATION_COMPONENT_PREVIEW_IMAGES_DECORATOR_H_
#define DUST3D_APPLICATION_COMPONENT_PREVIEW_IMAGES_DECORATOR_H_ #define DUST3D_APPLICATION_COMPONENT_PREVIEW_IMAGES_DECORATOR_H_
#include <QImage>
#include <dust3d/base/uuid.h>
#include <memory> #include <memory>
#include <unordered_map> #include <unordered_map>
#include <dust3d/base/uuid.h>
#include <QImage>
class ComponentPreviewImagesDecorator: public QObject class ComponentPreviewImagesDecorator : public QObject {
{
Q_OBJECT Q_OBJECT
public: public:
struct PreviewInput struct PreviewInput {
{
dust3d::Uuid id; dust3d::Uuid id;
std::unique_ptr<QImage> image; std::unique_ptr<QImage> image;
bool isDirectory = false; bool isDirectory = false;
@ -23,6 +21,7 @@ signals:
void finished(); void finished();
public slots: public slots:
void process(); void process();
private: private:
std::unique_ptr<std::vector<PreviewInput>> m_previewInputs; std::unique_ptr<std::vector<PreviewInput>> m_previewInputs;
std::unique_ptr<std::unordered_map<dust3d::Uuid, std::unique_ptr<QImage>>> m_resultImages; std::unique_ptr<std::unordered_map<dust3d::Uuid, std::unique_ptr<QImage>>> m_resultImages;

View File

@ -1,96 +1,96 @@
#include <unordered_set> #include "component_property_widget.h"
#include <QVBoxLayout> #include "document.h"
#include <QHBoxLayout> #include "float_number_widget.h"
#include <QPushButton> #include "theme.h"
#include <QColorDialog> #include <QColorDialog>
#include <QGroupBox> #include <QGroupBox>
#include "component_property_widget.h" #include <QHBoxLayout>
#include "float_number_widget.h" #include <QPushButton>
#include "document.h" #include <QVBoxLayout>
#include "theme.h" #include <unordered_set>
ComponentPropertyWidget::ComponentPropertyWidget(Document *document, ComponentPropertyWidget::ComponentPropertyWidget(Document* document,
const std::vector<dust3d::Uuid> &componentIds, const std::vector<dust3d::Uuid>& componentIds,
QWidget *parent): QWidget* parent)
QWidget(parent), : QWidget(parent)
m_document(document), , m_document(document)
m_componentIds(componentIds) , m_componentIds(componentIds)
{ {
preparePartIds(); preparePartIds();
m_color = lastColor(); m_color = lastColor();
QPushButton *colorPreviewArea = new QPushButton; QPushButton* colorPreviewArea = new QPushButton;
colorPreviewArea->setStyleSheet("QPushButton {background-color: " + m_color.name() + "; border-radius: 0;}"); colorPreviewArea->setStyleSheet("QPushButton {background-color: " + m_color.name() + "; border-radius: 0;}");
colorPreviewArea->setFixedSize(Theme::toolIconSize * 1.8, Theme::toolIconSize); colorPreviewArea->setFixedSize(Theme::toolIconSize * 1.8, Theme::toolIconSize);
QPushButton *colorPickerButton = new QPushButton(QChar(fa::eyedropper)); QPushButton* colorPickerButton = new QPushButton(QChar(fa::eyedropper));
Theme::initIconButton(colorPickerButton); Theme::initIconButton(colorPickerButton);
connect(colorPickerButton, &QPushButton::clicked, this, &ComponentPropertyWidget::showColorDialog); connect(colorPickerButton, &QPushButton::clicked, this, &ComponentPropertyWidget::showColorDialog);
QHBoxLayout *colorLayout = new QHBoxLayout; QHBoxLayout* colorLayout = new QHBoxLayout;
colorLayout->addWidget(colorPreviewArea); colorLayout->addWidget(colorPreviewArea);
colorLayout->addWidget(colorPickerButton); colorLayout->addWidget(colorPickerButton);
colorLayout->addStretch(); colorLayout->addStretch();
colorLayout->setSizeConstraint(QLayout::SetFixedSize); colorLayout->setSizeConstraint(QLayout::SetFixedSize);
QGroupBox *deformGroupBox = nullptr; QGroupBox* deformGroupBox = nullptr;
if (nullptr != m_part) { if (nullptr != m_part) {
FloatNumberWidget *thicknessWidget = new FloatNumberWidget; FloatNumberWidget* thicknessWidget = new FloatNumberWidget;
thicknessWidget->setItemName(tr("Thickness")); thicknessWidget->setItemName(tr("Thickness"));
thicknessWidget->setRange(0, 2); thicknessWidget->setRange(0, 2);
thicknessWidget->setValue(m_part->deformThickness); thicknessWidget->setValue(m_part->deformThickness);
connect(thicknessWidget, &FloatNumberWidget::valueChanged, [=](float value) { connect(thicknessWidget, &FloatNumberWidget::valueChanged, [=](float value) {
emit setPartDeformThickness(m_partId, value); emit setPartDeformThickness(m_partId, value);
emit groupOperationAdded(); emit groupOperationAdded();
}); });
FloatNumberWidget *widthWidget = new FloatNumberWidget; FloatNumberWidget* widthWidget = new FloatNumberWidget;
widthWidget->setItemName(tr("Width")); widthWidget->setItemName(tr("Width"));
widthWidget->setRange(0, 2); widthWidget->setRange(0, 2);
widthWidget->setValue(m_part->deformWidth); widthWidget->setValue(m_part->deformWidth);
connect(widthWidget, &FloatNumberWidget::valueChanged, [=](float value) { connect(widthWidget, &FloatNumberWidget::valueChanged, [=](float value) {
emit setPartDeformWidth(m_partId, value); emit setPartDeformWidth(m_partId, value);
emit groupOperationAdded(); emit groupOperationAdded();
}); });
QPushButton *thicknessEraser = new QPushButton(QChar(fa::eraser)); QPushButton* thicknessEraser = new QPushButton(QChar(fa::eraser));
Theme::initIconButton(thicknessEraser); Theme::initIconButton(thicknessEraser);
connect(thicknessEraser, &QPushButton::clicked, [=]() { connect(thicknessEraser, &QPushButton::clicked, [=]() {
thicknessWidget->setValue(1.0); thicknessWidget->setValue(1.0);
emit groupOperationAdded(); emit groupOperationAdded();
}); });
QPushButton *widthEraser = new QPushButton(QChar(fa::eraser)); QPushButton* widthEraser = new QPushButton(QChar(fa::eraser));
Theme::initIconButton(widthEraser); Theme::initIconButton(widthEraser);
connect(widthEraser, &QPushButton::clicked, [=]() { connect(widthEraser, &QPushButton::clicked, [=]() {
widthWidget->setValue(1.0); widthWidget->setValue(1.0);
emit groupOperationAdded(); emit groupOperationAdded();
}); });
QVBoxLayout *deformLayout = new QVBoxLayout; QVBoxLayout* deformLayout = new QVBoxLayout;
QHBoxLayout *thicknessLayout = new QHBoxLayout; QHBoxLayout* thicknessLayout = new QHBoxLayout;
QHBoxLayout *widthLayout = new QHBoxLayout; QHBoxLayout* widthLayout = new QHBoxLayout;
thicknessLayout->addWidget(thicknessEraser); thicknessLayout->addWidget(thicknessEraser);
thicknessLayout->addWidget(thicknessWidget); thicknessLayout->addWidget(thicknessWidget);
widthLayout->addWidget(widthEraser); widthLayout->addWidget(widthEraser);
widthLayout->addWidget(widthWidget); widthLayout->addWidget(widthWidget);
QCheckBox *deformUnifyStateBox = new QCheckBox(); QCheckBox* deformUnifyStateBox = new QCheckBox();
Theme::initCheckbox(deformUnifyStateBox); Theme::initCheckbox(deformUnifyStateBox);
deformUnifyStateBox->setText(tr("Unified")); deformUnifyStateBox->setText(tr("Unified"));
deformUnifyStateBox->setChecked(m_part->deformUnified); deformUnifyStateBox->setChecked(m_part->deformUnified);
connect(deformUnifyStateBox, &QCheckBox::stateChanged, this, [=]() { connect(deformUnifyStateBox, &QCheckBox::stateChanged, this, [=]() {
emit setPartDeformUnified(m_partId, deformUnifyStateBox->isChecked()); emit setPartDeformUnified(m_partId, deformUnifyStateBox->isChecked());
emit groupOperationAdded(); emit groupOperationAdded();
}); });
QHBoxLayout *deformUnifyLayout = new QHBoxLayout; QHBoxLayout* deformUnifyLayout = new QHBoxLayout;
deformUnifyLayout->addStretch(); deformUnifyLayout->addStretch();
deformUnifyLayout->addWidget(deformUnifyStateBox); deformUnifyLayout->addWidget(deformUnifyStateBox);
@ -102,85 +102,85 @@ ComponentPropertyWidget::ComponentPropertyWidget(Document *document,
deformGroupBox->setLayout(deformLayout); deformGroupBox->setLayout(deformLayout);
} }
QGroupBox *cutFaceGroupBox = nullptr; QGroupBox* cutFaceGroupBox = nullptr;
if (nullptr != m_part) { if (nullptr != m_part) {
FloatNumberWidget *rotationWidget = new FloatNumberWidget; FloatNumberWidget* rotationWidget = new FloatNumberWidget;
rotationWidget->setItemName(tr("Rotation")); rotationWidget->setItemName(tr("Rotation"));
rotationWidget->setRange(-1, 1); rotationWidget->setRange(-1, 1);
rotationWidget->setValue(m_part->cutRotation); rotationWidget->setValue(m_part->cutRotation);
connect(rotationWidget, &FloatNumberWidget::valueChanged, [=](float value) { connect(rotationWidget, &FloatNumberWidget::valueChanged, [=](float value) {
emit setPartCutRotation(m_partId, value); emit setPartCutRotation(m_partId, value);
emit groupOperationAdded(); emit groupOperationAdded();
}); });
QPushButton *rotationEraser = new QPushButton(QChar(fa::eraser)); QPushButton* rotationEraser = new QPushButton(QChar(fa::eraser));
Theme::initIconButton(rotationEraser); Theme::initIconButton(rotationEraser);
connect(rotationEraser, &QPushButton::clicked, [=]() { connect(rotationEraser, &QPushButton::clicked, [=]() {
rotationWidget->setValue(0.0); rotationWidget->setValue(0.0);
emit groupOperationAdded(); emit groupOperationAdded();
}); });
QPushButton *rotationMinus5Button = new QPushButton(QChar(fa::rotateleft)); QPushButton* rotationMinus5Button = new QPushButton(QChar(fa::rotateleft));
Theme::initIconButton(rotationMinus5Button); Theme::initIconButton(rotationMinus5Button);
connect(rotationMinus5Button, &QPushButton::clicked, [=]() { connect(rotationMinus5Button, &QPushButton::clicked, [=]() {
rotationWidget->setValue(-0.5); rotationWidget->setValue(-0.5);
emit groupOperationAdded(); emit groupOperationAdded();
}); });
QPushButton *rotation5Button = new QPushButton(QChar(fa::rotateright)); QPushButton* rotation5Button = new QPushButton(QChar(fa::rotateright));
Theme::initIconButton(rotation5Button); Theme::initIconButton(rotation5Button);
connect(rotation5Button, &QPushButton::clicked, [=]() { connect(rotation5Button, &QPushButton::clicked, [=]() {
rotationWidget->setValue(0.5); rotationWidget->setValue(0.5);
emit groupOperationAdded(); emit groupOperationAdded();
}); });
QHBoxLayout *rotationLayout = new QHBoxLayout; QHBoxLayout* rotationLayout = new QHBoxLayout;
rotationLayout->addWidget(rotationEraser); rotationLayout->addWidget(rotationEraser);
rotationLayout->addWidget(rotationWidget); rotationLayout->addWidget(rotationWidget);
rotationLayout->addWidget(rotationMinus5Button); rotationLayout->addWidget(rotationMinus5Button);
rotationLayout->addWidget(rotation5Button); rotationLayout->addWidget(rotation5Button);
QCheckBox *subdivStateBox = new QCheckBox(); QCheckBox* subdivStateBox = new QCheckBox();
Theme::initCheckbox(subdivStateBox); Theme::initCheckbox(subdivStateBox);
subdivStateBox->setText(tr("Subdivided")); subdivStateBox->setText(tr("Subdivided"));
subdivStateBox->setChecked(m_part->subdived); subdivStateBox->setChecked(m_part->subdived);
connect(subdivStateBox, &QCheckBox::stateChanged, this, [=]() { connect(subdivStateBox, &QCheckBox::stateChanged, this, [=]() {
emit setPartSubdivState(m_partId, subdivStateBox->isChecked()); emit setPartSubdivState(m_partId, subdivStateBox->isChecked());
emit groupOperationAdded(); emit groupOperationAdded();
}); });
QCheckBox *chamferStateBox = new QCheckBox(); QCheckBox* chamferStateBox = new QCheckBox();
Theme::initCheckbox(chamferStateBox); Theme::initCheckbox(chamferStateBox);
chamferStateBox->setText(tr("Chamfered")); chamferStateBox->setText(tr("Chamfered"));
chamferStateBox->setChecked(m_part->chamfered); chamferStateBox->setChecked(m_part->chamfered);
connect(chamferStateBox, &QCheckBox::stateChanged, this, [=]() { connect(chamferStateBox, &QCheckBox::stateChanged, this, [=]() {
emit setPartChamferState(m_partId, chamferStateBox->isChecked()); emit setPartChamferState(m_partId, chamferStateBox->isChecked());
emit groupOperationAdded(); emit groupOperationAdded();
}); });
QCheckBox *roundEndStateBox = new QCheckBox(); QCheckBox* roundEndStateBox = new QCheckBox();
Theme::initCheckbox(roundEndStateBox); Theme::initCheckbox(roundEndStateBox);
roundEndStateBox->setText(tr("Round end")); roundEndStateBox->setText(tr("Round end"));
roundEndStateBox->setChecked(m_part->rounded); roundEndStateBox->setChecked(m_part->rounded);
connect(roundEndStateBox, &QCheckBox::stateChanged, this, [=]() { connect(roundEndStateBox, &QCheckBox::stateChanged, this, [=]() {
emit setPartRoundState(m_partId, roundEndStateBox->isChecked()); emit setPartRoundState(m_partId, roundEndStateBox->isChecked());
emit groupOperationAdded(); emit groupOperationAdded();
}); });
QHBoxLayout *optionsLayout = new QHBoxLayout; QHBoxLayout* optionsLayout = new QHBoxLayout;
optionsLayout->addStretch(); optionsLayout->addStretch();
optionsLayout->addWidget(roundEndStateBox); optionsLayout->addWidget(roundEndStateBox);
optionsLayout->addWidget(chamferStateBox); optionsLayout->addWidget(chamferStateBox);
optionsLayout->addWidget(subdivStateBox); optionsLayout->addWidget(subdivStateBox);
QVBoxLayout *cutFaceLayout = new QVBoxLayout; QVBoxLayout* cutFaceLayout = new QVBoxLayout;
cutFaceLayout->addLayout(rotationLayout); cutFaceLayout->addLayout(rotationLayout);
cutFaceLayout->addLayout(optionsLayout); cutFaceLayout->addLayout(optionsLayout);
@ -188,7 +188,7 @@ ComponentPropertyWidget::ComponentPropertyWidget(Document *document,
cutFaceGroupBox->setLayout(cutFaceLayout); cutFaceGroupBox->setLayout(cutFaceLayout);
} }
QVBoxLayout *mainLayout = new QVBoxLayout; QVBoxLayout* mainLayout = new QVBoxLayout;
mainLayout->addLayout(colorLayout); mainLayout->addLayout(colorLayout);
if (nullptr != deformGroupBox) if (nullptr != deformGroupBox)
mainLayout->addWidget(deformGroupBox); mainLayout->addWidget(deformGroupBox);
@ -216,10 +216,10 @@ ComponentPropertyWidget::ComponentPropertyWidget(Document *document,
void ComponentPropertyWidget::preparePartIds() void ComponentPropertyWidget::preparePartIds()
{ {
std::unordered_set<dust3d::Uuid> addedPartIdSet; std::unordered_set<dust3d::Uuid> addedPartIdSet;
for (const auto &componentId: m_componentIds) { for (const auto& componentId : m_componentIds) {
std::vector<dust3d::Uuid> partIds; std::vector<dust3d::Uuid> partIds;
m_document->collectComponentDescendantParts(componentId, partIds); m_document->collectComponentDescendantParts(componentId, partIds);
for (const auto &it: partIds) { for (const auto& it : partIds) {
if (addedPartIdSet.insert(it).second) if (addedPartIdSet.insert(it).second)
m_partIds.emplace_back(it); m_partIds.emplace_back(it);
} }
@ -234,18 +234,18 @@ void ComponentPropertyWidget::preparePartIds()
QColor ComponentPropertyWidget::lastColor() QColor ComponentPropertyWidget::lastColor()
{ {
QColor color = Qt::white; QColor color = Qt::white;
std::map<QString, int> colorMap; std::map<QString, int> colorMap;
for (const auto &partId: m_partIds) { for (const auto& partId : m_partIds) {
const SkeletonPart *part = m_document->findPart(partId); const SkeletonPart* part = m_document->findPart(partId);
if (nullptr == part) if (nullptr == part)
continue; continue;
colorMap[part->color.name()]++; colorMap[part->color.name()]++;
} }
if (!colorMap.empty()) { if (!colorMap.empty()) {
color = std::max_element(colorMap.begin(), colorMap.end(), color = std::max_element(colorMap.begin(), colorMap.end(),
[](const std::map<QString, int>::value_type &a, const std::map<QString, int>::value_type &b) { [](const std::map<QString, int>::value_type& a, const std::map<QString, int>::value_type& b) {
return a.second < b.second; return a.second < b.second;
})->first; })->first;
} }
return color; return color;
} }
@ -258,7 +258,7 @@ void ComponentPropertyWidget::showColorDialog()
if (!color.isValid()) if (!color.isValid())
return; return;
for (const auto &partId: m_partIds) { for (const auto& partId : m_partIds) {
emit setPartColorState(partId, true, color); emit setPartColorState(partId, true, color);
} }
emit groupOperationAdded(); emit groupOperationAdded();

View File

@ -1,39 +1,40 @@
#ifndef DUST3D_APPLICATION_COMPONENT_PROPERTY_WIDGET_H_ #ifndef DUST3D_APPLICATION_COMPONENT_PROPERTY_WIDGET_H_
#define DUST3D_APPLICATION_COMPONENT_PROPERTY_WIDGET_H_ #define DUST3D_APPLICATION_COMPONENT_PROPERTY_WIDGET_H_
#include <dust3d/base/uuid.h>
#include <QWidget> #include <QWidget>
#include <dust3d/base/uuid.h>
class Document; class Document;
class SkeletonPart; class SkeletonPart;
class ComponentPropertyWidget: public QWidget class ComponentPropertyWidget : public QWidget {
{
Q_OBJECT Q_OBJECT
signals: signals:
void beginColorPicking(); void beginColorPicking();
void endColorPicking(); void endColorPicking();
void setPartColorState(const dust3d::Uuid &partId, bool hasColor, const QColor &color); void setPartColorState(const dust3d::Uuid& partId, bool hasColor, const QColor& color);
void setPartDeformThickness(const dust3d::Uuid &partId, float thickness); void setPartDeformThickness(const dust3d::Uuid& partId, float thickness);
void setPartDeformWidth(const dust3d::Uuid &partId, float width); void setPartDeformWidth(const dust3d::Uuid& partId, float width);
void setPartDeformUnified(const dust3d::Uuid &partId, bool unified); void setPartDeformUnified(const dust3d::Uuid& partId, bool unified);
void setPartSubdivState(const dust3d::Uuid &partId, bool subdived); void setPartSubdivState(const dust3d::Uuid& partId, bool subdived);
void setPartChamferState(const dust3d::Uuid &partId, bool chamfered); void setPartChamferState(const dust3d::Uuid& partId, bool chamfered);
void setPartRoundState(const dust3d::Uuid &partId, bool rounded); void setPartRoundState(const dust3d::Uuid& partId, bool rounded);
void setPartCutRotation(const dust3d::Uuid &partId, float cutRotation); void setPartCutRotation(const dust3d::Uuid& partId, float cutRotation);
void groupOperationAdded(); void groupOperationAdded();
public: public:
ComponentPropertyWidget(Document *document, ComponentPropertyWidget(Document* document,
const std::vector<dust3d::Uuid> &componentIds, const std::vector<dust3d::Uuid>& componentIds,
QWidget *parent=nullptr); QWidget* parent = nullptr);
public slots: public slots:
void showColorDialog(); void showColorDialog();
private: private:
Document *m_document = nullptr; Document* m_document = nullptr;
std::vector<dust3d::Uuid> m_componentIds; std::vector<dust3d::Uuid> m_componentIds;
std::vector<dust3d::Uuid> m_partIds; std::vector<dust3d::Uuid> m_partIds;
dust3d::Uuid m_partId; dust3d::Uuid m_partId;
const SkeletonPart *m_part = nullptr; const SkeletonPart* m_part = nullptr;
QColor m_color; QColor m_color;
QColor lastColor(); QColor lastColor();
void preparePartIds(); void preparePartIds();

View File

@ -1,15 +1,15 @@
#include <QPainter>
#include <QPainterPath>
#include "cut_face_preview.h" #include "cut_face_preview.h"
#include "theme.h" #include "theme.h"
#include <QPainter>
#include <QPainterPath>
static std::map<int, QImage *> g_standardCutFaceMap; static std::map<int, QImage*> g_standardCutFaceMap;
QImage *buildCutFaceTemplatePreviewImage(const std::vector<dust3d::Vector2> &cutTemplate) QImage* buildCutFaceTemplatePreviewImage(const std::vector<dust3d::Vector2>& cutTemplate)
{ {
QImage *image = new QImage(Theme::partPreviewImageSize, Theme::partPreviewImageSize, QImage::Format_ARGB32); QImage* image = new QImage(Theme::partPreviewImageSize, Theme::partPreviewImageSize, QImage::Format_ARGB32);
image->fill(Qt::transparent); image->fill(Qt::transparent);
if (cutTemplate.empty()) if (cutTemplate.empty())
return image; return image;
@ -17,41 +17,41 @@ QImage *buildCutFaceTemplatePreviewImage(const std::vector<dust3d::Vector2> &cut
painter.begin(image); painter.begin(image);
painter.setRenderHint(QPainter::Antialiasing); painter.setRenderHint(QPainter::Antialiasing);
painter.setRenderHint(QPainter::HighQualityAntialiasing); painter.setRenderHint(QPainter::HighQualityAntialiasing);
QPen pen(Theme::red, 2); QPen pen(Theme::red, 2);
painter.setPen(pen); painter.setPen(pen);
QBrush brush; QBrush brush;
brush.setColor(Theme::white); brush.setColor(Theme::white);
brush.setStyle(Qt::SolidPattern); brush.setStyle(Qt::SolidPattern);
painter.setBrush(brush); painter.setBrush(brush);
const float scale = 0.7f; const float scale = 0.7f;
QPolygon polygon; QPolygon polygon;
for (size_t i = 0; i <= cutTemplate.size(); ++i) { for (size_t i = 0; i <= cutTemplate.size(); ++i) {
const auto &it = cutTemplate[i % cutTemplate.size()]; const auto& it = cutTemplate[i % cutTemplate.size()];
polygon.append(QPoint((it.x() * scale + 1.0) * 0.5 * Theme::partPreviewImageSize, polygon.append(QPoint((it.x() * scale + 1.0) * 0.5 * Theme::partPreviewImageSize,
(it.y() * scale + 1.0) * 0.5 * Theme::partPreviewImageSize)); (it.y() * scale + 1.0) * 0.5 * Theme::partPreviewImageSize));
} }
QPainterPath path; QPainterPath path;
path.addPolygon(polygon); path.addPolygon(polygon);
painter.fillPath(path, brush); painter.fillPath(path, brush);
painter.drawPath(path); painter.drawPath(path);
painter.end(); painter.end();
return image; return image;
} }
const QImage *cutFacePreviewImage(dust3d::CutFace cutFace) const QImage* cutFacePreviewImage(dust3d::CutFace cutFace)
{ {
auto findItem = g_standardCutFaceMap.find((int)cutFace); auto findItem = g_standardCutFaceMap.find((int)cutFace);
if (findItem != g_standardCutFaceMap.end()) if (findItem != g_standardCutFaceMap.end())
return findItem->second; return findItem->second;
std::vector<dust3d::Vector2> cutTemplate = dust3d::CutFaceToPoints(cutFace); std::vector<dust3d::Vector2> cutTemplate = dust3d::CutFaceToPoints(cutFace);
QImage *image = buildCutFaceTemplatePreviewImage(cutTemplate); QImage* image = buildCutFaceTemplatePreviewImage(cutTemplate);
g_standardCutFaceMap.insert({(int)cutFace, image}); g_standardCutFaceMap.insert({ (int)cutFace, image });
return image; return image;
} }

View File

@ -4,7 +4,7 @@
#include <QImage> #include <QImage>
#include <dust3d/base/cut_face.h> #include <dust3d/base/cut_face.h>
QImage *buildCutFaceTemplatePreviewImage(const std::vector<dust3d::Vector2> &cutTemplate); QImage* buildCutFaceTemplatePreviewImage(const std::vector<dust3d::Vector2>& cutTemplate);
const QImage *cutFacePreviewImage(dust3d::CutFace cutFace); const QImage* cutFacePreviewImage(dust3d::CutFace cutFace);
#endif #endif

View File

@ -1,10 +1,10 @@
#include <QtGlobal>
#include <QFile>
#include <QDebug>
#include <QtEndian>
#include <QByteArray>
#include <QOpenGLPixelTransferOptions>
#include "dds_file.h" #include "dds_file.h"
#include <QByteArray>
#include <QDebug>
#include <QFile>
#include <QOpenGLPixelTransferOptions>
#include <QtEndian>
#include <QtGlobal>
#ifndef _WIN32 #ifndef _WIN32
typedef quint32 DWORD; typedef quint32 DWORD;
@ -37,20 +37,20 @@ typedef enum {
} DDS_CAPS2_FLAGS; } DDS_CAPS2_FLAGS;
typedef struct { typedef struct {
DWORD dwSize; DWORD dwSize;
DWORD dwFlags; DWORD dwFlags;
DWORD dwHeight; DWORD dwHeight;
DWORD dwWidth; DWORD dwWidth;
DWORD dwPitchOrLinearSize; DWORD dwPitchOrLinearSize;
DWORD dwDepth; DWORD dwDepth;
DWORD dwMipMapCount; DWORD dwMipMapCount;
DWORD dwReserved1[11]; DWORD dwReserved1[11];
DDS_PIXELFORMAT ddspf; DDS_PIXELFORMAT ddspf;
DWORD dwCaps; DWORD dwCaps;
DWORD dwCaps2; DWORD dwCaps2;
DWORD dwCaps3; DWORD dwCaps3;
DWORD dwCaps4; DWORD dwCaps4;
DWORD dwReserved2; DWORD dwReserved2;
} DDS_HEADER; } DDS_HEADER;
typedef enum { typedef enum {
@ -176,9 +176,9 @@ typedef enum {
DXGI_FORMAT_FORCE_UINT DXGI_FORMAT_FORCE_UINT
} DXGI_FORMAT; } DXGI_FORMAT;
static const char *DxgiFormatToString(DXGI_FORMAT dxgiFormat) static const char* DxgiFormatToString(DXGI_FORMAT dxgiFormat)
{ {
static const char *names[] = { static const char* names[] = {
"DXGI_FORMAT_UNKNOWN", "DXGI_FORMAT_UNKNOWN",
"DXGI_FORMAT_R32G32B32A32_TYPELESS", "DXGI_FORMAT_R32G32B32A32_TYPELESS",
"DXGI_FORMAT_R32G32B32A32_FLOAT", "DXGI_FORMAT_R32G32B32A32_FLOAT",
@ -314,9 +314,9 @@ typedef enum {
D3D10_RESOURCE_DIMENSION_TEXTURE3D D3D10_RESOURCE_DIMENSION_TEXTURE3D
} D3D10_RESOURCE_DIMENSION; } D3D10_RESOURCE_DIMENSION;
static const char *ResourceDimensionToString(D3D10_RESOURCE_DIMENSION resourceDimension) static const char* ResourceDimensionToString(D3D10_RESOURCE_DIMENSION resourceDimension)
{ {
static const char *names[] = { static const char* names[] = {
"D3D10_RESOURCE_DIMENSION_UNKNOWN", "D3D10_RESOURCE_DIMENSION_UNKNOWN",
"D3D10_RESOURCE_DIMENSION_BUFFER", "D3D10_RESOURCE_DIMENSION_BUFFER",
"D3D10_RESOURCE_DIMENSION_TEXTURE1D", "D3D10_RESOURCE_DIMENSION_TEXTURE1D",
@ -337,9 +337,9 @@ typedef enum {
D3D10_RESOURCE_MISC_GDI_COMPATIBLE D3D10_RESOURCE_MISC_GDI_COMPATIBLE
} D3D10_RESOURCE_MISC_FLAG; } D3D10_RESOURCE_MISC_FLAG;
static const char *MiscFlagToString(UINT miscFlag) static const char* MiscFlagToString(UINT miscFlag)
{ {
static const char *names[] = { static const char* names[] = {
"D3D10_RESOURCE_MISC_GENERATE_MIPS", "D3D10_RESOURCE_MISC_GENERATE_MIPS",
"D3D10_RESOURCE_MISC_SHARED", "D3D10_RESOURCE_MISC_SHARED",
"D3D10_RESOURCE_MISC_TEXTURECUBE", "D3D10_RESOURCE_MISC_TEXTURECUBE",
@ -353,76 +353,76 @@ static const char *MiscFlagToString(UINT miscFlag)
} }
typedef struct { typedef struct {
DXGI_FORMAT dxgiFormat; DXGI_FORMAT dxgiFormat;
D3D10_RESOURCE_DIMENSION resourceDimension; D3D10_RESOURCE_DIMENSION resourceDimension;
UINT miscFlag; UINT miscFlag;
UINT arraySize; UINT arraySize;
UINT miscFlags2; UINT miscFlags2;
} DDS_HEADER_DXT10; } DDS_HEADER_DXT10;
typedef struct { typedef struct {
DWORD dwMagic; DWORD dwMagic;
DDS_HEADER header; DDS_HEADER header;
DDS_HEADER_DXT10 header10; DDS_HEADER_DXT10 header10;
} DDS_FILE_HEADER; } DDS_FILE_HEADER;
DdsFileReader::DdsFileReader(const QString &filename) : DdsFileReader::DdsFileReader(const QString& filename)
m_filename(filename) : m_filename(filename)
{ {
} }
std::unique_ptr<std::vector<std::unique_ptr<QOpenGLTexture>>> DdsFileReader::createOpenGLTextures() std::unique_ptr<std::vector<std::unique_ptr<QOpenGLTexture>>> DdsFileReader::createOpenGLTextures()
{ {
QFile file(m_filename); QFile file(m_filename);
if (!file.open(QIODevice::ReadOnly)) { if (!file.open(QIODevice::ReadOnly)) {
qDebug() << "Open" << m_filename << "failed"; qDebug() << "Open" << m_filename << "failed";
return nullptr; return nullptr;
} }
DDS_FILE_HEADER fileHeader; DDS_FILE_HEADER fileHeader;
if (sizeof(fileHeader) != file.read((char *)&fileHeader, sizeof(fileHeader))) { if (sizeof(fileHeader) != file.read((char*)&fileHeader, sizeof(fileHeader))) {
qDebug() << "Read DDS file hader failed"; qDebug() << "Read DDS file hader failed";
return nullptr; return nullptr;
} }
if (0x20534444 != qFromLittleEndian<quint32>(&fileHeader.dwMagic)) { if (0x20534444 != qFromLittleEndian<quint32>(&fileHeader.dwMagic)) {
qDebug() << "Not a DDS file"; qDebug() << "Not a DDS file";
return nullptr; return nullptr;
} }
if (0x30315844 != qFromLittleEndian<quint32>(&fileHeader.header.ddspf.dwFourCC)) { if (0x30315844 != qFromLittleEndian<quint32>(&fileHeader.header.ddspf.dwFourCC)) {
qDebug() << "Unsupported DDS file, expected DX10 file"; qDebug() << "Unsupported DDS file, expected DX10 file";
return nullptr; return nullptr;
} }
auto caps2 = qFromLittleEndian<quint32>(&fileHeader.header.dwCaps2); auto caps2 = qFromLittleEndian<quint32>(&fileHeader.header.dwCaps2);
if (!(DDSCAPS2_CUBEMAP & caps2)) { if (!(DDSCAPS2_CUBEMAP & caps2)) {
qDebug() << "Unsupported DDS file, expected CUBEMAP file"; qDebug() << "Unsupported DDS file, expected CUBEMAP file";
return nullptr; return nullptr;
} }
//qDebug() << "Start anyalize DDS file..."; //qDebug() << "Start anyalize DDS file...";
int width = qFromLittleEndian<quint32>(&fileHeader.header.dwWidth); int width = qFromLittleEndian<quint32>(&fileHeader.header.dwWidth);
int height = qFromLittleEndian<quint32>(&fileHeader.header.dwHeight); int height = qFromLittleEndian<quint32>(&fileHeader.header.dwHeight);
//qDebug() << "DDS size:" << width << "X" << height; //qDebug() << "DDS size:" << width << "X" << height;
//auto pitchOrLinearSize = qFromLittleEndian<quint32>(&fileHeader.header.dwPitchOrLinearSize); //auto pitchOrLinearSize = qFromLittleEndian<quint32>(&fileHeader.header.dwPitchOrLinearSize);
//qDebug() << "DDS pitch or linear size:" << pitchOrLinearSize; //qDebug() << "DDS pitch or linear size:" << pitchOrLinearSize;
auto arraySize = qFromLittleEndian<quint32>(&fileHeader.header10.arraySize); auto arraySize = qFromLittleEndian<quint32>(&fileHeader.header10.arraySize);
//qDebug() << "DDS array size:" << arraySize; //qDebug() << "DDS array size:" << arraySize;
auto mipMapCount = qFromLittleEndian<quint32>(&fileHeader.header.dwMipMapCount); auto mipMapCount = qFromLittleEndian<quint32>(&fileHeader.header.dwMipMapCount);
//qDebug() << "DDS mip map count:" << mipMapCount; //qDebug() << "DDS mip map count:" << mipMapCount;
DXGI_FORMAT dxgiFormat = (DXGI_FORMAT)qFromLittleEndian<quint32>(&fileHeader.header10.dxgiFormat); DXGI_FORMAT dxgiFormat = (DXGI_FORMAT)qFromLittleEndian<quint32>(&fileHeader.header10.dxgiFormat);
//qDebug() << "DDS dxgi format:" << DxgiFormatToString(dxgiFormat); //qDebug() << "DDS dxgi format:" << DxgiFormatToString(dxgiFormat);
//qDebug() << "DDS resource dimension:" << ResourceDimensionToString((D3D10_RESOURCE_DIMENSION)qFromLittleEndian<quint32>(&fileHeader.header10.resourceDimension)); //qDebug() << "DDS resource dimension:" << ResourceDimensionToString((D3D10_RESOURCE_DIMENSION)qFromLittleEndian<quint32>(&fileHeader.header10.resourceDimension));
//qDebug() << "DDS misc flag:" << MiscFlagToString((UINT)qFromLittleEndian<quint32>(&fileHeader.header10.miscFlag)); //qDebug() << "DDS misc flag:" << MiscFlagToString((UINT)qFromLittleEndian<quint32>(&fileHeader.header10.miscFlag));
quint32 faces = 0; quint32 faces = 0;
if (DDSCAPS2_CUBEMAP_POSITIVEX & caps2) { if (DDSCAPS2_CUBEMAP_POSITIVEX & caps2) {
//qDebug() << "DDS found +x"; //qDebug() << "DDS found +x";
@ -448,20 +448,20 @@ std::unique_ptr<std::vector<std::unique_ptr<QOpenGLTexture>>> DdsFileReader::cre
//qDebug() << "DDS found -z"; //qDebug() << "DDS found -z";
++faces; ++faces;
} }
if (6 != faces) { if (6 != faces) {
qDebug() << "Unsupported DDS file, expected six faces"; qDebug() << "Unsupported DDS file, expected six faces";
return nullptr; return nullptr;
} }
if (1 != arraySize) { if (1 != arraySize) {
qDebug() << "Unsupported DDS file, expected one layer"; qDebug() << "Unsupported DDS file, expected one layer";
return nullptr; return nullptr;
} }
if (DXGI_FORMAT_R16G16B16A16_FLOAT != dxgiFormat) { if (DXGI_FORMAT_R16G16B16A16_FLOAT != dxgiFormat) {
qDebug() << "Unsupported DDS file, expected dxgi format: DXGI_FORMAT_R16G16B16A16_FLOAT"; qDebug() << "Unsupported DDS file, expected dxgi format: DXGI_FORMAT_R16G16B16A16_FLOAT";
return nullptr; return nullptr;
} }
int components = 8; int components = 8;
int oneFaceSize = 0; int oneFaceSize = 0;
@ -479,7 +479,7 @@ std::unique_ptr<std::vector<std::unique_ptr<QOpenGLTexture>>> DdsFileReader::cre
} }
int depth = 1; int depth = 1;
auto textures = std::make_unique<std::vector<std::unique_ptr<QOpenGLTexture>>>(); auto textures = std::make_unique<std::vector<std::unique_ptr<QOpenGLTexture>>>();
textures->resize(6); textures->resize(6);
@ -488,7 +488,7 @@ std::unique_ptr<std::vector<std::unique_ptr<QOpenGLTexture>>> DdsFileReader::cre
for (quint32 face = 0; face < faces; ++face) { for (quint32 face = 0; face < faces; ++face) {
for (quint32 level = 0; level < mipMapCount; ++level) { for (quint32 level = 0; level < mipMapCount; ++level) {
if (0 == layer && 0 == level) { if (0 == layer && 0 == level) {
QOpenGLTexture *texture = new QOpenGLTexture(QOpenGLTexture::Target2D); QOpenGLTexture* texture = new QOpenGLTexture(QOpenGLTexture::Target2D);
texture->setMinificationFilter(QOpenGLTexture::NearestMipMapNearest); texture->setMinificationFilter(QOpenGLTexture::NearestMipMapNearest);
texture->setMagnificationFilter(QOpenGLTexture::Nearest); texture->setMagnificationFilter(QOpenGLTexture::Nearest);
texture->setFormat(QOpenGLTexture::RGBA16F); texture->setFormat(QOpenGLTexture::RGBA16F);
@ -504,58 +504,58 @@ std::unique_ptr<std::vector<std::unique_ptr<QOpenGLTexture>>> DdsFileReader::cre
return std::move(textures); return std::move(textures);
} }
QOpenGLTexture *DdsFileReader::createOpenGLTexture() QOpenGLTexture* DdsFileReader::createOpenGLTexture()
{ {
QFile file(m_filename); QFile file(m_filename);
if (!file.open(QIODevice::ReadOnly)) { if (!file.open(QIODevice::ReadOnly)) {
qDebug() << "Open" << m_filename << "failed"; qDebug() << "Open" << m_filename << "failed";
return nullptr; return nullptr;
} }
DDS_FILE_HEADER fileHeader; DDS_FILE_HEADER fileHeader;
if (sizeof(fileHeader) != file.read((char *)&fileHeader, sizeof(fileHeader))) { if (sizeof(fileHeader) != file.read((char*)&fileHeader, sizeof(fileHeader))) {
qDebug() << "Read DDS file hader failed"; qDebug() << "Read DDS file hader failed";
return nullptr; return nullptr;
} }
if (0x20534444 != qFromLittleEndian<quint32>(&fileHeader.dwMagic)) { if (0x20534444 != qFromLittleEndian<quint32>(&fileHeader.dwMagic)) {
qDebug() << "Not a DDS file"; qDebug() << "Not a DDS file";
return nullptr; return nullptr;
} }
if (0x30315844 != qFromLittleEndian<quint32>(&fileHeader.header.ddspf.dwFourCC)) { if (0x30315844 != qFromLittleEndian<quint32>(&fileHeader.header.ddspf.dwFourCC)) {
qDebug() << "Unsupported DDS file, expected DX10 file"; qDebug() << "Unsupported DDS file, expected DX10 file";
return nullptr; return nullptr;
} }
auto caps2 = qFromLittleEndian<quint32>(&fileHeader.header.dwCaps2); auto caps2 = qFromLittleEndian<quint32>(&fileHeader.header.dwCaps2);
if (!(DDSCAPS2_CUBEMAP & caps2)) { if (!(DDSCAPS2_CUBEMAP & caps2)) {
qDebug() << "Unsupported DDS file, expected CUBEMAP file"; qDebug() << "Unsupported DDS file, expected CUBEMAP file";
return nullptr; return nullptr;
} }
//qDebug() << "Start anyalize DDS file..."; //qDebug() << "Start anyalize DDS file...";
int width = qFromLittleEndian<quint32>(&fileHeader.header.dwWidth); int width = qFromLittleEndian<quint32>(&fileHeader.header.dwWidth);
int height = qFromLittleEndian<quint32>(&fileHeader.header.dwHeight); int height = qFromLittleEndian<quint32>(&fileHeader.header.dwHeight);
//qDebug() << "DDS size:" << width << "X" << height; //qDebug() << "DDS size:" << width << "X" << height;
//auto pitchOrLinearSize = qFromLittleEndian<quint32>(&fileHeader.header.dwPitchOrLinearSize); //auto pitchOrLinearSize = qFromLittleEndian<quint32>(&fileHeader.header.dwPitchOrLinearSize);
//qDebug() << "DDS pitch or linear size:" << pitchOrLinearSize; //qDebug() << "DDS pitch or linear size:" << pitchOrLinearSize;
auto arraySize = qFromLittleEndian<quint32>(&fileHeader.header10.arraySize); auto arraySize = qFromLittleEndian<quint32>(&fileHeader.header10.arraySize);
//qDebug() << "DDS array size:" << arraySize; //qDebug() << "DDS array size:" << arraySize;
auto mipMapCount = qFromLittleEndian<quint32>(&fileHeader.header.dwMipMapCount); auto mipMapCount = qFromLittleEndian<quint32>(&fileHeader.header.dwMipMapCount);
//qDebug() << "DDS mip map count:" << mipMapCount; //qDebug() << "DDS mip map count:" << mipMapCount;
DXGI_FORMAT dxgiFormat = (DXGI_FORMAT)qFromLittleEndian<quint32>(&fileHeader.header10.dxgiFormat); DXGI_FORMAT dxgiFormat = (DXGI_FORMAT)qFromLittleEndian<quint32>(&fileHeader.header10.dxgiFormat);
//qDebug() << "DDS dxgi format:" << DxgiFormatToString(dxgiFormat); //qDebug() << "DDS dxgi format:" << DxgiFormatToString(dxgiFormat);
//qDebug() << "DDS resource dimension:" << ResourceDimensionToString((D3D10_RESOURCE_DIMENSION)qFromLittleEndian<quint32>(&fileHeader.header10.resourceDimension)); //qDebug() << "DDS resource dimension:" << ResourceDimensionToString((D3D10_RESOURCE_DIMENSION)qFromLittleEndian<quint32>(&fileHeader.header10.resourceDimension));
//qDebug() << "DDS misc flag:" << MiscFlagToString((UINT)qFromLittleEndian<quint32>(&fileHeader.header10.miscFlag)); //qDebug() << "DDS misc flag:" << MiscFlagToString((UINT)qFromLittleEndian<quint32>(&fileHeader.header10.miscFlag));
quint32 faces = 0; quint32 faces = 0;
if (DDSCAPS2_CUBEMAP_POSITIVEX & caps2) { if (DDSCAPS2_CUBEMAP_POSITIVEX & caps2) {
//qDebug() << "DDS found +x"; //qDebug() << "DDS found +x";
@ -581,20 +581,20 @@ QOpenGLTexture *DdsFileReader::createOpenGLTexture()
//qDebug() << "DDS found -z"; //qDebug() << "DDS found -z";
++faces; ++faces;
} }
if (6 != faces) { if (6 != faces) {
qDebug() << "Unsupported DDS file, expected six faces"; qDebug() << "Unsupported DDS file, expected six faces";
return nullptr; return nullptr;
} }
if (1 != arraySize) { if (1 != arraySize) {
qDebug() << "Unsupported DDS file, expected one layer"; qDebug() << "Unsupported DDS file, expected one layer";
return nullptr; return nullptr;
} }
if (DXGI_FORMAT_R16G16B16A16_FLOAT != dxgiFormat) { if (DXGI_FORMAT_R16G16B16A16_FLOAT != dxgiFormat) {
qDebug() << "Unsupported DDS file, expected dxgi format: DXGI_FORMAT_R16G16B16A16_FLOAT"; qDebug() << "Unsupported DDS file, expected dxgi format: DXGI_FORMAT_R16G16B16A16_FLOAT";
return nullptr; return nullptr;
} }
int components = 8; int components = 8;
int oneFaceSize = 0; int oneFaceSize = 0;
@ -610,9 +610,9 @@ QOpenGLTexture *DdsFileReader::createOpenGLTexture()
qDebug() << "DDS file invalid, expected total size:" << totalSize << "read size:" << data.size(); qDebug() << "DDS file invalid, expected total size:" << totalSize << "read size:" << data.size();
return nullptr; return nullptr;
} }
int depth = 1; int depth = 1;
QOpenGLTexture* texture = new QOpenGLTexture(QOpenGLTexture::TargetCubeMap); QOpenGLTexture* texture = new QOpenGLTexture(QOpenGLTexture::TargetCubeMap);
texture->setFormat(QOpenGLTexture::RGBA16F); texture->setFormat(QOpenGLTexture::RGBA16F);
texture->setSize(width, height, depth); texture->setSize(width, height, depth);
@ -620,37 +620,37 @@ QOpenGLTexture *DdsFileReader::createOpenGLTexture()
texture->setMipBaseLevel(0); texture->setMipBaseLevel(0);
texture->setMipMaxLevel(mipMapCount - 1); texture->setMipMaxLevel(mipMapCount - 1);
texture->setMipLevels(mipMapCount); texture->setMipLevels(mipMapCount);
if (!texture->create()) { if (!texture->create()) {
qDebug() << "QOpenGLTexture::create failed"; qDebug() << "QOpenGLTexture::create failed";
delete texture; delete texture;
return nullptr; return nullptr;
} }
texture->allocateStorage(); texture->allocateStorage();
if (!texture->isStorageAllocated()) { if (!texture->isStorageAllocated()) {
qDebug() << "QOpenGLTexture::isStorageAllocated false"; qDebug() << "QOpenGLTexture::isStorageAllocated false";
delete texture; delete texture;
return nullptr; return nullptr;
} }
uint64_t dataOffset = 0; uint64_t dataOffset = 0;
for (quint32 layer = 0; layer < arraySize; ++layer) { for (quint32 layer = 0; layer < arraySize; ++layer) {
for (quint32 face = 0; face < faces; ++face) { for (quint32 face = 0; face < faces; ++face) {
for (quint32 level = 0; level < mipMapCount; ++level) { for (quint32 level = 0; level < mipMapCount; ++level) {
QOpenGLPixelTransferOptions uploadOptions; QOpenGLPixelTransferOptions uploadOptions;
uploadOptions.setAlignment(1); uploadOptions.setAlignment(1);
texture->setData(level, texture->setData(level,
layer, layer,
static_cast<QOpenGLTexture::CubeMapFace>(QOpenGLTexture::CubeMapPositiveX + face), static_cast<QOpenGLTexture::CubeMapFace>(QOpenGLTexture::CubeMapPositiveX + face),
QOpenGLTexture::RGBA, QOpenGLTexture::RGBA,
QOpenGLTexture::Float16, QOpenGLTexture::Float16,
data.constData() + dataOffset, data.constData() + dataOffset,
&uploadOptions); &uploadOptions);
dataOffset += calculateOneFaceSizeAtLevel(level); dataOffset += calculateOneFaceSizeAtLevel(level);
} }
} }
} }
return texture; return texture;
} }

View File

@ -1,16 +1,16 @@
#ifndef DUST3D_APPLICATION_DDS_FILE_H_ #ifndef DUST3D_APPLICATION_DDS_FILE_H_
#define DUST3D_APPLICATION_DDS_FILE_H_ #define DUST3D_APPLICATION_DDS_FILE_H_
#include <memory>
#include <QString>
#include <QOpenGLTexture> #include <QOpenGLTexture>
#include <QString>
#include <memory>
class DdsFileReader class DdsFileReader {
{
public: public:
DdsFileReader(const QString &filename); DdsFileReader(const QString& filename);
QOpenGLTexture *createOpenGLTexture(); QOpenGLTexture* createOpenGLTexture();
std::unique_ptr<std::vector<std::unique_ptr<QOpenGLTexture>>> createOpenGLTextures(); std::unique_ptr<std::vector<std::unique_ptr<QOpenGLTexture>>> createOpenGLTextures();
private: private:
QString m_filename; QString m_filename;
}; };

View File

@ -1,13 +1,13 @@
#include "debug.h" #include "debug.h"
QDebug operator<<(QDebug debug, const dust3d::Uuid &uuid) QDebug operator<<(QDebug debug, const dust3d::Uuid& uuid)
{ {
QDebugStateSaver stateSaver(debug); QDebugStateSaver stateSaver(debug);
debug.nospace() << uuid.toString().c_str(); debug.nospace() << uuid.toString().c_str();
return debug; return debug;
} }
QDebug operator<<(QDebug debug, const std::string &string) QDebug operator<<(QDebug debug, const std::string& string)
{ {
QDebugStateSaver stateSaver(debug); QDebugStateSaver stateSaver(debug);
debug.nospace() << string.c_str(); debug.nospace() << string.c_str();

View File

@ -4,7 +4,7 @@
#include <QDebug> #include <QDebug>
#include <dust3d/base/uuid.h> #include <dust3d/base/uuid.h>
QDebug operator<<(QDebug debug, const dust3d::Uuid &uuid); QDebug operator<<(QDebug debug, const dust3d::Uuid& uuid);
QDebug operator<<(QDebug debug, const std::string &string); QDebug operator<<(QDebug debug, const std::string& string);
#endif #endif

View File

@ -1,34 +1,34 @@
#include <QFileDialog>
#include <QDebug>
#include <QThread>
#include <QGuiApplication>
#include <QClipboard>
#include <QMimeData>
#include <QApplication>
#include <QVector3D>
#include <functional>
#include <QtCore/qbuffer.h>
#include <QElapsedTimer>
#include <queue>
#include <dust3d/base/snapshot_xml.h>
#include <dust3d/base/texture_type.h>
#include "document.h" #include "document.h"
#include "image_forever.h" #include "image_forever.h"
#include "material_previews_generator.h"
#include "mesh_generator.h" #include "mesh_generator.h"
#include "mesh_result_post_processor.h" #include "mesh_result_post_processor.h"
#include "texture_generator.h" #include "texture_generator.h"
#include "material_previews_generator.h" #include <QApplication>
#include <QClipboard>
#include <QDebug>
#include <QElapsedTimer>
#include <QFileDialog>
#include <QGuiApplication>
#include <QMimeData>
#include <QThread>
#include <QVector3D>
#include <QtCore/qbuffer.h>
#include <dust3d/base/snapshot_xml.h>
#include <dust3d/base/texture_type.h>
#include <functional>
#include <queue>
unsigned long Document::m_maxSnapshot = 1000; unsigned long Document::m_maxSnapshot = 1000;
Document::Document() : Document::Document()
SkeletonDocument() : SkeletonDocument()
{ {
} }
Document::~Document() Document::~Document()
{ {
delete (dust3d::MeshGenerator::GeneratedCacheContext *)m_generatedCacheContext; delete (dust3d::MeshGenerator::GeneratedCacheContext*)m_generatedCacheContext;
delete m_resultMesh; delete m_resultMesh;
delete m_postProcessedObject; delete m_postProcessedObject;
delete textureImage; delete textureImage;
@ -55,7 +55,7 @@ bool Document::originSettled() const
return !qFuzzyIsNull(getOriginX()) && !qFuzzyIsNull(getOriginY()) && !qFuzzyIsNull(getOriginZ()); return !qFuzzyIsNull(getOriginX()) && !qFuzzyIsNull(getOriginY()) && !qFuzzyIsNull(getOriginZ());
} }
const Material *Document::findMaterial(dust3d::Uuid materialId) const const Material* Document::findMaterial(dust3d::Uuid materialId) const
{ {
auto it = materialMap.find(materialId); auto it = materialMap.find(materialId);
if (it == materialMap.end()) if (it == materialMap.end())
@ -104,8 +104,7 @@ void Document::setNodeCutFaceLinkedId(dust3d::Uuid nodeId, dust3d::Uuid linkedId
qDebug() << "Node not found:" << nodeId; qDebug() << "Node not found:" << nodeId;
return; return;
} }
if (node->second.cutFace == dust3d::CutFace::UserDefined && if (node->second.cutFace == dust3d::CutFace::UserDefined && node->second.cutFaceLinkedId == linkedId)
node->second.cutFaceLinkedId == linkedId)
return; return;
node->second.setCutFaceLinkedId(linkedId); node->second.setCutFaceLinkedId(linkedId);
auto part = partMap.find(node->second.partId); auto part = partMap.find(node->second.partId);
@ -132,7 +131,7 @@ void Document::clearNodeCutFaceSettings(dust3d::Uuid nodeId)
emit skeletonChanged(); emit skeletonChanged();
} }
void Document::updateTurnaround(const QImage &image) void Document::updateTurnaround(const QImage& image)
{ {
turnaround = image; turnaround = image;
turnaroundPngByteArray.clear(); turnaroundPngByteArray.clear();
@ -149,47 +148,47 @@ void Document::clearTurnaround()
emit turnaroundChanged(); emit turnaroundChanged();
} }
void Document::updateTextureImage(QImage *image) void Document::updateTextureImage(QImage* image)
{ {
delete textureImageByteArray; delete textureImageByteArray;
textureImageByteArray = nullptr; textureImageByteArray = nullptr;
delete textureImage; delete textureImage;
textureImage = image; textureImage = image;
} }
void Document::updateTextureNormalImage(QImage *image) void Document::updateTextureNormalImage(QImage* image)
{ {
delete textureNormalImageByteArray; delete textureNormalImageByteArray;
textureNormalImageByteArray = nullptr; textureNormalImageByteArray = nullptr;
delete textureNormalImage; delete textureNormalImage;
textureNormalImage = image; textureNormalImage = image;
} }
void Document::updateTextureMetalnessImage(QImage *image) void Document::updateTextureMetalnessImage(QImage* image)
{ {
delete textureMetalnessImageByteArray; delete textureMetalnessImageByteArray;
textureMetalnessImageByteArray = nullptr; textureMetalnessImageByteArray = nullptr;
delete textureMetalnessImage; delete textureMetalnessImage;
textureMetalnessImage = image; textureMetalnessImage = image;
} }
void Document::updateTextureRoughnessImage(QImage *image) void Document::updateTextureRoughnessImage(QImage* image)
{ {
delete textureRoughnessImageByteArray; delete textureRoughnessImageByteArray;
textureRoughnessImageByteArray = nullptr; textureRoughnessImageByteArray = nullptr;
delete textureRoughnessImage; delete textureRoughnessImage;
textureRoughnessImage = image; textureRoughnessImage = image;
} }
void Document::updateTextureAmbientOcclusionImage(QImage *image) void Document::updateTextureAmbientOcclusionImage(QImage* image)
{ {
delete textureAmbientOcclusionImageByteArray; delete textureAmbientOcclusionImageByteArray;
textureAmbientOcclusionImageByteArray = nullptr; textureAmbientOcclusionImageByteArray = nullptr;
delete textureAmbientOcclusionImage; delete textureAmbientOcclusionImage;
textureAmbientOcclusionImage = image; textureAmbientOcclusionImage = image;
} }
@ -198,28 +197,27 @@ void Document::setEditMode(SkeletonDocumentEditMode mode)
{ {
if (editMode == mode) if (editMode == mode)
return; return;
editMode = mode; editMode = mode;
emit editModeChanged(); emit editModeChanged();
} }
void Document::toSnapshot(dust3d::Snapshot *snapshot, const std::set<dust3d::Uuid> &limitNodeIds, void Document::toSnapshot(dust3d::Snapshot* snapshot, const std::set<dust3d::Uuid>& limitNodeIds,
DocumentToSnapshotFor forWhat, DocumentToSnapshotFor forWhat,
const std::set<dust3d::Uuid> &limitMaterialIds) const const std::set<dust3d::Uuid>& limitMaterialIds) const
{ {
if (DocumentToSnapshotFor::Document == forWhat || if (DocumentToSnapshotFor::Document == forWhat || DocumentToSnapshotFor::Nodes == forWhat) {
DocumentToSnapshotFor::Nodes == forWhat) {
std::set<dust3d::Uuid> limitPartIds; std::set<dust3d::Uuid> limitPartIds;
std::set<dust3d::Uuid> limitComponentIds; std::set<dust3d::Uuid> limitComponentIds;
for (const auto &nodeId: limitNodeIds) { for (const auto& nodeId : limitNodeIds) {
const SkeletonNode *node = findNode(nodeId); const SkeletonNode* node = findNode(nodeId);
if (!node) if (!node)
continue; continue;
const SkeletonPart *part = findPart(node->partId); const SkeletonPart* part = findPart(node->partId);
if (!part) if (!part)
continue; continue;
limitPartIds.insert(node->partId); limitPartIds.insert(node->partId);
const SkeletonComponent *component = findComponent(part->componentId); const SkeletonComponent* component = findComponent(part->componentId);
while (component) { while (component) {
limitComponentIds.insert(component->id); limitComponentIds.insert(component->id);
if (component->id.isNull()) if (component->id.isNull())
@ -227,7 +225,7 @@ void Document::toSnapshot(dust3d::Snapshot *snapshot, const std::set<dust3d::Uui
component = findComponent(component->parentId); component = findComponent(component->parentId);
} }
} }
for (const auto &partIt : partMap) { for (const auto& partIt : partMap) {
if (!limitPartIds.empty() && limitPartIds.find(partIt.first) == limitPartIds.end()) if (!limitPartIds.empty() && limitPartIds.find(partIt.first) == limitPartIds.end())
continue; continue;
std::map<std::string, std::string> part; std::map<std::string, std::string> part;
@ -281,7 +279,7 @@ void Document::toSnapshot(dust3d::Snapshot *snapshot, const std::set<dust3d::Uui
part["smooth"] = "true"; part["smooth"] = "true";
snapshot->parts[part["id"]] = part; snapshot->parts[part["id"]] = part;
} }
for (const auto &nodeIt: nodeMap) { for (const auto& nodeIt : nodeMap) {
if (!limitNodeIds.empty() && limitNodeIds.find(nodeIt.first) == limitNodeIds.end()) if (!limitNodeIds.empty() && limitNodeIds.find(nodeIt.first) == limitNodeIds.end())
continue; continue;
std::map<std::string, std::string> node; std::map<std::string, std::string> node;
@ -305,12 +303,10 @@ void Document::toSnapshot(dust3d::Snapshot *snapshot, const std::set<dust3d::Uui
node["name"] = nodeIt.second.name.toUtf8().constData(); node["name"] = nodeIt.second.name.toUtf8().constData();
snapshot->nodes[node["id"]] = node; snapshot->nodes[node["id"]] = node;
} }
for (const auto &edgeIt: edgeMap) { for (const auto& edgeIt : edgeMap) {
if (edgeIt.second.nodeIds.size() != 2) if (edgeIt.second.nodeIds.size() != 2)
continue; continue;
if (!limitNodeIds.empty() && if (!limitNodeIds.empty() && (limitNodeIds.find(edgeIt.second.nodeIds[0]) == limitNodeIds.end() || limitNodeIds.find(edgeIt.second.nodeIds[1]) == limitNodeIds.end()))
(limitNodeIds.find(edgeIt.second.nodeIds[0]) == limitNodeIds.end() ||
limitNodeIds.find(edgeIt.second.nodeIds[1]) == limitNodeIds.end()))
continue; continue;
std::map<std::string, std::string> edge; std::map<std::string, std::string> edge;
edge["id"] = edgeIt.second.id.toString(); edge["id"] = edgeIt.second.id.toString();
@ -321,7 +317,7 @@ void Document::toSnapshot(dust3d::Snapshot *snapshot, const std::set<dust3d::Uui
edge["name"] = edgeIt.second.name.toUtf8().constData(); edge["name"] = edgeIt.second.name.toUtf8().constData();
snapshot->edges[edge["id"]] = edge; snapshot->edges[edge["id"]] = edge;
} }
for (const auto &componentIt: componentMap) { for (const auto& componentIt : componentMap) {
if (!limitComponentIds.empty() && limitComponentIds.find(componentIt.first) == limitComponentIds.end()) if (!limitComponentIds.empty() && limitComponentIds.find(componentIt.first) == limitComponentIds.end())
continue; continue;
std::map<std::string, std::string> component; std::map<std::string, std::string> component;
@ -332,7 +328,7 @@ void Document::toSnapshot(dust3d::Snapshot *snapshot, const std::set<dust3d::Uui
component["combineMode"] = CombineModeToString(componentIt.second.combineMode); component["combineMode"] = CombineModeToString(componentIt.second.combineMode);
component["__dirty"] = componentIt.second.dirty ? "true" : "false"; component["__dirty"] = componentIt.second.dirty ? "true" : "false";
std::vector<std::string> childIdList; std::vector<std::string> childIdList;
for (const auto &childId: componentIt.second.childrenIds) { for (const auto& childId : componentIt.second.childrenIds) {
childIdList.push_back(childId.toString()); childIdList.push_back(childId.toString());
} }
std::string children = dust3d::String::join(childIdList, ","); std::string children = dust3d::String::join(childIdList, ",");
@ -349,7 +345,7 @@ void Document::toSnapshot(dust3d::Snapshot *snapshot, const std::set<dust3d::Uui
} }
if (limitComponentIds.empty() || limitComponentIds.find(dust3d::Uuid()) != limitComponentIds.end()) { if (limitComponentIds.empty() || limitComponentIds.find(dust3d::Uuid()) != limitComponentIds.end()) {
std::vector<std::string> childIdList; std::vector<std::string> childIdList;
for (const auto &childId: rootComponent.childrenIds) { for (const auto& childId : rootComponent.childrenIds) {
childIdList.push_back(childId.toString()); childIdList.push_back(childId.toString());
} }
std::string children = dust3d::String::join(childIdList, ","); std::string children = dust3d::String::join(childIdList, ",");
@ -357,9 +353,8 @@ void Document::toSnapshot(dust3d::Snapshot *snapshot, const std::set<dust3d::Uui
snapshot->rootComponent["children"] = children; snapshot->rootComponent["children"] = children;
} }
} }
if (DocumentToSnapshotFor::Document == forWhat || if (DocumentToSnapshotFor::Document == forWhat || DocumentToSnapshotFor::Materials == forWhat) {
DocumentToSnapshotFor::Materials == forWhat) { for (const auto& materialId : materialIdList) {
for (const auto &materialId: materialIdList) {
if (!limitMaterialIds.empty() && limitMaterialIds.find(materialId) == limitMaterialIds.end()) if (!limitMaterialIds.empty() && limitMaterialIds.find(materialId) == limitMaterialIds.end())
continue; continue;
auto findMaterialResult = materialMap.find(materialId); auto findMaterialResult = materialMap.find(materialId);
@ -367,16 +362,16 @@ void Document::toSnapshot(dust3d::Snapshot *snapshot, const std::set<dust3d::Uui
qDebug() << "Find material failed:" << materialId; qDebug() << "Find material failed:" << materialId;
continue; continue;
} }
auto &materialIt = *findMaterialResult; auto& materialIt = *findMaterialResult;
std::map<std::string, std::string> material; std::map<std::string, std::string> material;
material["id"] = materialIt.second.id.toString(); material["id"] = materialIt.second.id.toString();
material["type"] = "MetalRoughness"; material["type"] = "MetalRoughness";
if (!materialIt.second.name.isEmpty()) if (!materialIt.second.name.isEmpty())
material["name"] = materialIt.second.name.toUtf8().constData(); material["name"] = materialIt.second.name.toUtf8().constData();
std::vector<std::pair<std::map<std::string, std::string>, std::vector<std::map<std::string, std::string>>>> layers; std::vector<std::pair<std::map<std::string, std::string>, std::vector<std::map<std::string, std::string>>>> layers;
for (const auto &layer: materialIt.second.layers) { for (const auto& layer : materialIt.second.layers) {
std::vector<std::map<std::string, std::string>> maps; std::vector<std::map<std::string, std::string>> maps;
for (const auto &mapItem: layer.maps) { for (const auto& mapItem : layer.maps) {
std::map<std::string, std::string> textureMap; std::map<std::string, std::string> textureMap;
textureMap["for"] = TextureTypeToString(mapItem.forWhat); textureMap["for"] = TextureTypeToString(mapItem.forWhat);
textureMap["linkDataType"] = "imageId"; textureMap["linkDataType"] = "imageId";
@ -386,7 +381,7 @@ void Document::toSnapshot(dust3d::Snapshot *snapshot, const std::set<dust3d::Uui
std::map<std::string, std::string> layerAttributes; std::map<std::string, std::string> layerAttributes;
if (!qFuzzyCompare((float)layer.tileScale, (float)1.0)) if (!qFuzzyCompare((float)layer.tileScale, (float)1.0))
layerAttributes["tileScale"] = std::to_string(layer.tileScale); layerAttributes["tileScale"] = std::to_string(layer.tileScale);
layers.push_back({layerAttributes, maps}); layers.push_back({ layerAttributes, maps });
} }
snapshot->materials.push_back(std::make_pair(material, layers)); snapshot->materials.push_back(std::make_pair(material, layers));
} }
@ -400,34 +395,31 @@ void Document::toSnapshot(dust3d::Snapshot *snapshot, const std::set<dust3d::Uui
} }
} }
void Document::addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSource source) void Document::addFromSnapshot(const dust3d::Snapshot& snapshot, enum SnapshotSource source)
{ {
bool isOriginChanged = false; bool isOriginChanged = false;
if (SnapshotSource::Paste != source && if (SnapshotSource::Paste != source && SnapshotSource::Import != source) {
SnapshotSource::Import != source) { const auto& originXit = snapshot.canvas.find("originX");
const auto &originXit = snapshot.canvas.find("originX"); const auto& originYit = snapshot.canvas.find("originY");
const auto &originYit = snapshot.canvas.find("originY"); const auto& originZit = snapshot.canvas.find("originZ");
const auto &originZit = snapshot.canvas.find("originZ"); if (originXit != snapshot.canvas.end() && originYit != snapshot.canvas.end() && originZit != snapshot.canvas.end()) {
if (originXit != snapshot.canvas.end() &&
originYit != snapshot.canvas.end() &&
originZit != snapshot.canvas.end()) {
setOriginX(dust3d::String::toFloat(originXit->second)); setOriginX(dust3d::String::toFloat(originXit->second));
setOriginY(dust3d::String::toFloat(originYit->second)); setOriginY(dust3d::String::toFloat(originYit->second));
setOriginZ(dust3d::String::toFloat(originZit->second)); setOriginZ(dust3d::String::toFloat(originZit->second));
isOriginChanged = true; isOriginChanged = true;
} }
} }
std::set<dust3d::Uuid> newAddedNodeIds; std::set<dust3d::Uuid> newAddedNodeIds;
std::set<dust3d::Uuid> newAddedEdgeIds; std::set<dust3d::Uuid> newAddedEdgeIds;
std::set<dust3d::Uuid> newAddedPartIds; std::set<dust3d::Uuid> newAddedPartIds;
std::set<dust3d::Uuid> newAddedComponentIds; std::set<dust3d::Uuid> newAddedComponentIds;
std::set<dust3d::Uuid> inversePartIds; std::set<dust3d::Uuid> inversePartIds;
std::map<dust3d::Uuid, dust3d::Uuid> oldNewIdMap; std::map<dust3d::Uuid, dust3d::Uuid> oldNewIdMap;
for (const auto &materialIt: snapshot.materials) { for (const auto& materialIt : snapshot.materials) {
const auto &materialAttributes = materialIt.first; const auto& materialAttributes = materialIt.first;
auto materialType = dust3d::String::valueOrEmpty(materialAttributes, "type"); auto materialType = dust3d::String::valueOrEmpty(materialAttributes, "type");
if ("MetalRoughness" != materialType) { if ("MetalRoughness" != materialType) {
qDebug() << "Unsupported material type:" << materialType; qDebug() << "Unsupported material type:" << materialType;
@ -437,15 +429,15 @@ void Document::addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSo
dust3d::Uuid newMaterialId = SnapshotSource::Import == source ? oldMaterialId : dust3d::Uuid::createUuid(); dust3d::Uuid newMaterialId = SnapshotSource::Import == source ? oldMaterialId : dust3d::Uuid::createUuid();
oldNewIdMap[oldMaterialId] = newMaterialId; oldNewIdMap[oldMaterialId] = newMaterialId;
if (materialMap.end() == materialMap.find(newMaterialId)) { if (materialMap.end() == materialMap.find(newMaterialId)) {
auto &newMaterial = materialMap[newMaterialId]; auto& newMaterial = materialMap[newMaterialId];
newMaterial.id = newMaterialId; newMaterial.id = newMaterialId;
newMaterial.name = dust3d::String::valueOrEmpty(materialAttributes, "name").c_str(); newMaterial.name = dust3d::String::valueOrEmpty(materialAttributes, "name").c_str();
for (const auto &layerIt: materialIt.second) { for (const auto& layerIt : materialIt.second) {
MaterialLayer layer; MaterialLayer layer;
auto findTileScale = layerIt.first.find("tileScale"); auto findTileScale = layerIt.first.find("tileScale");
if (findTileScale != layerIt.first.end()) if (findTileScale != layerIt.first.end())
layer.tileScale = dust3d::String::toFloat(findTileScale->second); layer.tileScale = dust3d::String::toFloat(findTileScale->second);
for (const auto &mapItem: layerIt.second) { for (const auto& mapItem : layerIt.second) {
auto textureTypeString = dust3d::String::valueOrEmpty(mapItem, "for"); auto textureTypeString = dust3d::String::valueOrEmpty(mapItem, "for");
auto textureType = dust3d::TextureTypeFromString(textureTypeString.c_str()); auto textureType = dust3d::TextureTypeFromString(textureTypeString.c_str());
if (dust3d::TextureType::None == textureType) { if (dust3d::TextureType::None == textureType) {
@ -470,13 +462,13 @@ void Document::addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSo
} }
} }
std::map<dust3d::Uuid, dust3d::Uuid> cutFaceLinkedIdModifyMap; std::map<dust3d::Uuid, dust3d::Uuid> cutFaceLinkedIdModifyMap;
for (const auto &partKv: snapshot.parts) { for (const auto& partKv : snapshot.parts) {
const auto newUuid = dust3d::Uuid::createUuid(); const auto newUuid = dust3d::Uuid::createUuid();
SkeletonPart &part = partMap[newUuid]; SkeletonPart& part = partMap[newUuid];
part.id = newUuid; part.id = newUuid;
oldNewIdMap[dust3d::Uuid(partKv.first)] = part.id; oldNewIdMap[dust3d::Uuid(partKv.first)] = part.id;
part.name = dust3d::String::valueOrEmpty(partKv.second, "name").c_str(); part.name = dust3d::String::valueOrEmpty(partKv.second, "name").c_str();
const auto &visibleIt = partKv.second.find("visible"); const auto& visibleIt = partKv.second.find("visible");
if (visibleIt != partKv.second.end()) { if (visibleIt != partKv.second.end()) {
part.visible = dust3d::String::isTrue(visibleIt->second); part.visible = dust3d::String::isTrue(visibleIt->second);
} else { } else {
@ -490,56 +482,56 @@ void Document::addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSo
part.rounded = dust3d::String::isTrue(dust3d::String::valueOrEmpty(partKv.second, "rounded")); part.rounded = dust3d::String::isTrue(dust3d::String::valueOrEmpty(partKv.second, "rounded"));
part.chamfered = dust3d::String::isTrue(dust3d::String::valueOrEmpty(partKv.second, "chamfered")); part.chamfered = dust3d::String::isTrue(dust3d::String::valueOrEmpty(partKv.second, "chamfered"));
part.target = dust3d::PartTargetFromString(dust3d::String::valueOrEmpty(partKv.second, "target").c_str()); part.target = dust3d::PartTargetFromString(dust3d::String::valueOrEmpty(partKv.second, "target").c_str());
const auto &cutRotationIt = partKv.second.find("cutRotation"); const auto& cutRotationIt = partKv.second.find("cutRotation");
if (cutRotationIt != partKv.second.end()) if (cutRotationIt != partKv.second.end())
part.setCutRotation(dust3d::String::toFloat(cutRotationIt->second)); part.setCutRotation(dust3d::String::toFloat(cutRotationIt->second));
const auto &cutFaceIt = partKv.second.find("cutFace"); const auto& cutFaceIt = partKv.second.find("cutFace");
if (cutFaceIt != partKv.second.end()) { if (cutFaceIt != partKv.second.end()) {
dust3d::Uuid cutFaceLinkedId = dust3d::Uuid(cutFaceIt->second); dust3d::Uuid cutFaceLinkedId = dust3d::Uuid(cutFaceIt->second);
if (cutFaceLinkedId.isNull()) { if (cutFaceLinkedId.isNull()) {
part.setCutFace(dust3d::CutFaceFromString(cutFaceIt->second.c_str())); part.setCutFace(dust3d::CutFaceFromString(cutFaceIt->second.c_str()));
} else { } else {
part.setCutFaceLinkedId(cutFaceLinkedId); part.setCutFaceLinkedId(cutFaceLinkedId);
cutFaceLinkedIdModifyMap.insert({part.id, cutFaceLinkedId}); cutFaceLinkedIdModifyMap.insert({ part.id, cutFaceLinkedId });
} }
} }
if (dust3d::String::isTrue(dust3d::String::valueOrEmpty(partKv.second, "inverse"))) if (dust3d::String::isTrue(dust3d::String::valueOrEmpty(partKv.second, "inverse")))
inversePartIds.insert(part.id); inversePartIds.insert(part.id);
const auto &colorIt = partKv.second.find("color"); const auto& colorIt = partKv.second.find("color");
if (colorIt != partKv.second.end()) { if (colorIt != partKv.second.end()) {
part.color = QColor(colorIt->second.c_str()); part.color = QColor(colorIt->second.c_str());
part.hasColor = true; part.hasColor = true;
} }
const auto &colorSolubilityIt = partKv.second.find("colorSolubility"); const auto& colorSolubilityIt = partKv.second.find("colorSolubility");
if (colorSolubilityIt != partKv.second.end()) if (colorSolubilityIt != partKv.second.end())
part.colorSolubility = dust3d::String::toFloat(colorSolubilityIt->second); part.colorSolubility = dust3d::String::toFloat(colorSolubilityIt->second);
const auto &metalnessIt = partKv.second.find("metallic"); const auto& metalnessIt = partKv.second.find("metallic");
if (metalnessIt != partKv.second.end()) if (metalnessIt != partKv.second.end())
part.metalness = dust3d::String::toFloat(metalnessIt->second); part.metalness = dust3d::String::toFloat(metalnessIt->second);
const auto &roughnessIt = partKv.second.find("roughness"); const auto& roughnessIt = partKv.second.find("roughness");
if (roughnessIt != partKv.second.end()) if (roughnessIt != partKv.second.end())
part.roughness = dust3d::String::toFloat(roughnessIt->second); part.roughness = dust3d::String::toFloat(roughnessIt->second);
const auto &deformThicknessIt = partKv.second.find("deformThickness"); const auto& deformThicknessIt = partKv.second.find("deformThickness");
if (deformThicknessIt != partKv.second.end()) if (deformThicknessIt != partKv.second.end())
part.setDeformThickness(dust3d::String::toFloat(deformThicknessIt->second)); part.setDeformThickness(dust3d::String::toFloat(deformThicknessIt->second));
const auto &deformWidthIt = partKv.second.find("deformWidth"); const auto& deformWidthIt = partKv.second.find("deformWidth");
if (deformWidthIt != partKv.second.end()) if (deformWidthIt != partKv.second.end())
part.setDeformWidth(dust3d::String::toFloat(deformWidthIt->second)); part.setDeformWidth(dust3d::String::toFloat(deformWidthIt->second));
const auto &deformUnifiedIt = partKv.second.find("deformUnified"); const auto& deformUnifiedIt = partKv.second.find("deformUnified");
if (deformUnifiedIt != partKv.second.end()) if (deformUnifiedIt != partKv.second.end())
part.deformUnified = dust3d::String::isTrue(dust3d::String::valueOrEmpty(partKv.second, "deformUnified")); part.deformUnified = dust3d::String::isTrue(dust3d::String::valueOrEmpty(partKv.second, "deformUnified"));
const auto &hollowThicknessIt = partKv.second.find("hollowThickness"); const auto& hollowThicknessIt = partKv.second.find("hollowThickness");
if (hollowThicknessIt != partKv.second.end()) if (hollowThicknessIt != partKv.second.end())
part.hollowThickness = dust3d::String::toFloat(hollowThicknessIt->second); part.hollowThickness = dust3d::String::toFloat(hollowThicknessIt->second);
const auto &materialIdIt = partKv.second.find("materialId"); const auto& materialIdIt = partKv.second.find("materialId");
if (materialIdIt != partKv.second.end()) if (materialIdIt != partKv.second.end())
part.materialId = oldNewIdMap[dust3d::Uuid(materialIdIt->second)]; part.materialId = oldNewIdMap[dust3d::Uuid(materialIdIt->second)];
part.countershaded = dust3d::String::isTrue(dust3d::String::valueOrEmpty(partKv.second, "countershaded")); part.countershaded = dust3d::String::isTrue(dust3d::String::valueOrEmpty(partKv.second, "countershaded"));
part.smooth = dust3d::String::isTrue(dust3d::String::valueOrEmpty(partKv.second, "smooth")); part.smooth = dust3d::String::isTrue(dust3d::String::valueOrEmpty(partKv.second, "smooth"));
newAddedPartIds.insert(part.id); newAddedPartIds.insert(part.id);
} }
for (const auto &it: cutFaceLinkedIdModifyMap) { for (const auto& it : cutFaceLinkedIdModifyMap) {
SkeletonPart &part = partMap[it.first]; SkeletonPart& part = partMap[it.first];
auto findNewLinkedId = oldNewIdMap.find(it.second); auto findNewLinkedId = oldNewIdMap.find(it.second);
if (findNewLinkedId == oldNewIdMap.end()) { if (findNewLinkedId == oldNewIdMap.end()) {
if (partMap.find(it.second) == partMap.end()) { if (partMap.find(it.second) == partMap.end()) {
@ -549,12 +541,8 @@ void Document::addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSo
part.setCutFaceLinkedId(findNewLinkedId->second); part.setCutFaceLinkedId(findNewLinkedId->second);
} }
} }
for (const auto &nodeKv: snapshot.nodes) { for (const auto& nodeKv : snapshot.nodes) {
if (nodeKv.second.find("radius") == nodeKv.second.end() || if (nodeKv.second.find("radius") == nodeKv.second.end() || nodeKv.second.find("x") == nodeKv.second.end() || nodeKv.second.find("y") == nodeKv.second.end() || nodeKv.second.find("z") == nodeKv.second.end() || nodeKv.second.find("partId") == nodeKv.second.end())
nodeKv.second.find("x") == nodeKv.second.end() ||
nodeKv.second.find("y") == nodeKv.second.end() ||
nodeKv.second.find("z") == nodeKv.second.end() ||
nodeKv.second.find("partId") == nodeKv.second.end())
continue; continue;
dust3d::Uuid oldNodeId = dust3d::Uuid(nodeKv.first); dust3d::Uuid oldNodeId = dust3d::Uuid(nodeKv.first);
SkeletonNode node(nodeMap.find(oldNodeId) == nodeMap.end() ? oldNodeId : dust3d::Uuid::createUuid()); SkeletonNode node(nodeMap.find(oldNodeId) == nodeMap.end() ? oldNodeId : dust3d::Uuid::createUuid());
@ -565,10 +553,10 @@ void Document::addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSo
node.setY(dust3d::String::toFloat(dust3d::String::valueOrEmpty(nodeKv.second, "y"))); node.setY(dust3d::String::toFloat(dust3d::String::valueOrEmpty(nodeKv.second, "y")));
node.setZ(dust3d::String::toFloat(dust3d::String::valueOrEmpty(nodeKv.second, "z"))); node.setZ(dust3d::String::toFloat(dust3d::String::valueOrEmpty(nodeKv.second, "z")));
node.partId = oldNewIdMap[dust3d::Uuid(dust3d::String::valueOrEmpty(nodeKv.second, "partId"))]; node.partId = oldNewIdMap[dust3d::Uuid(dust3d::String::valueOrEmpty(nodeKv.second, "partId"))];
const auto &cutRotationIt = nodeKv.second.find("cutRotation"); const auto& cutRotationIt = nodeKv.second.find("cutRotation");
if (cutRotationIt != nodeKv.second.end()) if (cutRotationIt != nodeKv.second.end())
node.setCutRotation(dust3d::String::toFloat(cutRotationIt->second)); node.setCutRotation(dust3d::String::toFloat(cutRotationIt->second));
const auto &cutFaceIt = nodeKv.second.find("cutFace"); const auto& cutFaceIt = nodeKv.second.find("cutFace");
if (cutFaceIt != nodeKv.second.end()) { if (cutFaceIt != nodeKv.second.end()) {
dust3d::Uuid cutFaceLinkedId = dust3d::Uuid(cutFaceIt->second); dust3d::Uuid cutFaceLinkedId = dust3d::Uuid(cutFaceIt->second);
if (cutFaceLinkedId.isNull()) { if (cutFaceLinkedId.isNull()) {
@ -588,10 +576,8 @@ void Document::addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSo
nodeMap[node.id] = node; nodeMap[node.id] = node;
newAddedNodeIds.insert(node.id); newAddedNodeIds.insert(node.id);
} }
for (const auto &edgeKv: snapshot.edges) { for (const auto& edgeKv : snapshot.edges) {
if (edgeKv.second.find("from") == edgeKv.second.end() || if (edgeKv.second.find("from") == edgeKv.second.end() || edgeKv.second.find("to") == edgeKv.second.end() || edgeKv.second.find("partId") == edgeKv.second.end())
edgeKv.second.find("to") == edgeKv.second.end() ||
edgeKv.second.find("partId") == edgeKv.second.end())
continue; continue;
dust3d::Uuid oldEdgeId = dust3d::Uuid(edgeKv.first); dust3d::Uuid oldEdgeId = dust3d::Uuid(edgeKv.first);
SkeletonEdge edge(edgeMap.find(oldEdgeId) == edgeMap.end() ? oldEdgeId : dust3d::Uuid::createUuid()); SkeletonEdge edge(edgeMap.find(oldEdgeId) == edgeMap.end() ? oldEdgeId : dust3d::Uuid::createUuid());
@ -613,12 +599,12 @@ void Document::addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSo
edgeMap[edge.id] = edge; edgeMap[edge.id] = edge;
newAddedEdgeIds.insert(edge.id); newAddedEdgeIds.insert(edge.id);
} }
for (const auto &nodeIt: nodeMap) { for (const auto& nodeIt : nodeMap) {
if (newAddedNodeIds.find(nodeIt.first) == newAddedNodeIds.end()) if (newAddedNodeIds.find(nodeIt.first) == newAddedNodeIds.end())
continue; continue;
partMap[nodeIt.second.partId].nodeIds.push_back(nodeIt.first); partMap[nodeIt.second.partId].nodeIds.push_back(nodeIt.first);
} }
for (const auto &componentKv: snapshot.components) { for (const auto& componentKv : snapshot.components) {
QString linkData = dust3d::String::valueOrEmpty(componentKv.second, "linkData").c_str(); QString linkData = dust3d::String::valueOrEmpty(componentKv.second, "linkData").c_str();
QString linkDataType = dust3d::String::valueOrEmpty(componentKv.second, "linkDataType").c_str(); QString linkDataType = dust3d::String::valueOrEmpty(componentKv.second, "linkDataType").c_str();
SkeletonComponent component(dust3d::Uuid(), linkData, linkDataType); SkeletonComponent component(dust3d::Uuid(), linkData, linkDataType);
@ -642,9 +628,9 @@ void Document::addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSo
componentMap.emplace(component.id, std::move(component)); componentMap.emplace(component.id, std::move(component));
newAddedComponentIds.insert(component.id); newAddedComponentIds.insert(component.id);
} }
const auto &rootComponentChildren = snapshot.rootComponent.find("children"); const auto& rootComponentChildren = snapshot.rootComponent.find("children");
if (rootComponentChildren != snapshot.rootComponent.end()) { if (rootComponentChildren != snapshot.rootComponent.end()) {
for (const auto &childId: dust3d::String::split(rootComponentChildren->second, ',')) { for (const auto& childId : dust3d::String::split(rootComponentChildren->second, ',')) {
if (childId.empty()) if (childId.empty())
continue; continue;
dust3d::Uuid componentId = oldNewIdMap[dust3d::Uuid(childId)]; dust3d::Uuid componentId = oldNewIdMap[dust3d::Uuid(childId)];
@ -654,11 +640,11 @@ void Document::addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSo
rootComponent.addChild(componentId); rootComponent.addChild(componentId);
} }
} }
for (const auto &componentKv: snapshot.components) { for (const auto& componentKv : snapshot.components) {
dust3d::Uuid componentId = oldNewIdMap[dust3d::Uuid(componentKv.first)]; dust3d::Uuid componentId = oldNewIdMap[dust3d::Uuid(componentKv.first)];
if (componentMap.find(componentId) == componentMap.end()) if (componentMap.find(componentId) == componentMap.end())
continue; continue;
for (const auto &childId: dust3d::String::split(dust3d::String::valueOrEmpty(componentKv.second, "children"), ',')) { for (const auto& childId : dust3d::String::split(dust3d::String::valueOrEmpty(componentKv.second, "children"), ',')) {
if (childId.empty()) if (childId.empty())
continue; continue;
dust3d::Uuid childComponentId = oldNewIdMap[dust3d::Uuid(childId)]; dust3d::Uuid childComponentId = oldNewIdMap[dust3d::Uuid(childId)];
@ -669,34 +655,34 @@ void Document::addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSo
componentMap[childComponentId].parentId = componentId; componentMap[childComponentId].parentId = componentId;
} }
} }
for (const auto &nodeIt: newAddedNodeIds) { for (const auto& nodeIt : newAddedNodeIds) {
emit nodeAdded(nodeIt); emit nodeAdded(nodeIt);
} }
for (const auto &edgeIt: newAddedEdgeIds) { for (const auto& edgeIt : newAddedEdgeIds) {
emit edgeAdded(edgeIt); emit edgeAdded(edgeIt);
} }
for (const auto &partIt : newAddedPartIds) { for (const auto& partIt : newAddedPartIds) {
emit partAdded(partIt); emit partAdded(partIt);
} }
emit componentChildrenChanged(dust3d::Uuid()); emit componentChildrenChanged(dust3d::Uuid());
if (isOriginChanged) if (isOriginChanged)
emit originChanged(); emit originChanged();
emit skeletonChanged(); emit skeletonChanged();
for (const auto &partIt : newAddedPartIds) { for (const auto& partIt : newAddedPartIds) {
emit partVisibleStateChanged(partIt); emit partVisibleStateChanged(partIt);
} }
emit uncheckAll(); emit uncheckAll();
for (const auto &nodeIt: newAddedNodeIds) { for (const auto& nodeIt : newAddedNodeIds) {
emit checkNode(nodeIt); emit checkNode(nodeIt);
} }
for (const auto &edgeIt: newAddedEdgeIds) { for (const auto& edgeIt : newAddedEdgeIds) {
emit checkEdge(edgeIt); emit checkEdge(edgeIt);
} }
if (!snapshot.materials.empty()) if (!snapshot.materials.empty())
emit materialListChanged(); emit materialListChanged();
} }
@ -722,22 +708,22 @@ void Document::reset()
emit skeletonChanged(); emit skeletonChanged();
} }
void Document::fromSnapshot(const dust3d::Snapshot &snapshot) void Document::fromSnapshot(const dust3d::Snapshot& snapshot)
{ {
reset(); reset();
addFromSnapshot(snapshot, SnapshotSource::Unknown); addFromSnapshot(snapshot, SnapshotSource::Unknown);
emit uncheckAll(); emit uncheckAll();
} }
ModelMesh *Document::takeResultMesh() ModelMesh* Document::takeResultMesh()
{ {
if (nullptr == m_resultMesh) if (nullptr == m_resultMesh)
return nullptr; return nullptr;
ModelMesh *resultMesh = new ModelMesh(*m_resultMesh); ModelMesh* resultMesh = new ModelMesh(*m_resultMesh);
return resultMesh; return resultMesh;
} }
MonochromeMesh *Document::takeWireframeMesh() MonochromeMesh* Document::takeWireframeMesh()
{ {
if (nullptr == m_wireframeMesh) if (nullptr == m_wireframeMesh)
return nullptr; return nullptr;
@ -749,51 +735,51 @@ bool Document::isMeshGenerationSucceed()
return m_isMeshGenerationSucceed; return m_isMeshGenerationSucceed;
} }
ModelMesh *Document::takeResultTextureMesh() ModelMesh* Document::takeResultTextureMesh()
{ {
if (nullptr == m_resultTextureMesh) if (nullptr == m_resultTextureMesh)
return nullptr; return nullptr;
ModelMesh *resultTextureMesh = new ModelMesh(*m_resultTextureMesh); ModelMesh* resultTextureMesh = new ModelMesh(*m_resultTextureMesh);
return resultTextureMesh; return resultTextureMesh;
} }
void Document::meshReady() void Document::meshReady()
{ {
ModelMesh *resultMesh = m_meshGenerator->takeResultMesh(); ModelMesh* resultMesh = m_meshGenerator->takeResultMesh();
m_wireframeMesh.reset(m_meshGenerator->takeWireframeMesh()); m_wireframeMesh.reset(m_meshGenerator->takeWireframeMesh());
dust3d::Object *object = m_meshGenerator->takeObject(); dust3d::Object* object = m_meshGenerator->takeObject();
bool isSuccessful = m_meshGenerator->isSuccessful(); bool isSuccessful = m_meshGenerator->isSuccessful();
std::unique_ptr<std::map<dust3d::Uuid, std::unique_ptr<ModelMesh>>> componentPreviewMeshes; std::unique_ptr<std::map<dust3d::Uuid, std::unique_ptr<ModelMesh>>> componentPreviewMeshes;
componentPreviewMeshes.reset(m_meshGenerator->takeComponentPreviewMeshes()); componentPreviewMeshes.reset(m_meshGenerator->takeComponentPreviewMeshes());
bool componentPreviewsChanged = componentPreviewMeshes && !componentPreviewMeshes->empty(); bool componentPreviewsChanged = componentPreviewMeshes && !componentPreviewMeshes->empty();
if (componentPreviewsChanged) { if (componentPreviewsChanged) {
for (auto &it: *componentPreviewMeshes) { for (auto& it : *componentPreviewMeshes) {
setComponentPreviewMesh(it.first, std::move(it.second)); setComponentPreviewMesh(it.first, std::move(it.second));
} }
emit resultComponentPreviewMeshesChanged(); emit resultComponentPreviewMeshesChanged();
} }
delete m_resultMesh; delete m_resultMesh;
m_resultMesh = resultMesh; m_resultMesh = resultMesh;
m_isMeshGenerationSucceed = isSuccessful; m_isMeshGenerationSucceed = isSuccessful;
delete m_currentObject; delete m_currentObject;
m_currentObject = object; m_currentObject = object;
if (nullptr == m_resultMesh) { if (nullptr == m_resultMesh) {
qDebug() << "Result mesh is null"; qDebug() << "Result mesh is null";
} }
delete m_meshGenerator; delete m_meshGenerator;
m_meshGenerator = nullptr; m_meshGenerator = nullptr;
qDebug() << "Mesh generation done"; qDebug() << "Mesh generation done";
m_isPostProcessResultObsolete = true; m_isPostProcessResultObsolete = true;
emit resultMeshChanged(); emit resultMeshChanged();
if (m_isResultMeshObsolete) { if (m_isResultMeshObsolete) {
generateMesh(); generateMesh();
} }
@ -843,18 +829,18 @@ void Document::generateMesh()
m_isResultMeshObsolete = true; m_isResultMeshObsolete = true;
return; return;
} }
emit meshGenerating(); emit meshGenerating();
qDebug() << "Mesh generating.."; qDebug() << "Mesh generating..";
settleOrigin(); settleOrigin();
m_isResultMeshObsolete = false; m_isResultMeshObsolete = false;
QThread *thread = new QThread; QThread* thread = new QThread;
dust3d::Snapshot *snapshot = new dust3d::Snapshot; dust3d::Snapshot* snapshot = new dust3d::Snapshot;
toSnapshot(snapshot); toSnapshot(snapshot);
resetDirtyFlags(); resetDirtyFlags();
m_meshGenerator = new MeshGenerator(snapshot); m_meshGenerator = new MeshGenerator(snapshot);
@ -862,7 +848,7 @@ void Document::generateMesh()
m_meshGenerator->setDefaultPartColor(dust3d::Color::createWhite()); m_meshGenerator->setDefaultPartColor(dust3d::Color::createWhite());
if (nullptr == m_generatedCacheContext) if (nullptr == m_generatedCacheContext)
m_generatedCacheContext = new MeshGenerator::GeneratedCacheContext; m_generatedCacheContext = new MeshGenerator::GeneratedCacheContext;
m_meshGenerator->setGeneratedCacheContext((dust3d::MeshGenerator::GeneratedCacheContext *)m_generatedCacheContext); m_meshGenerator->setGeneratedCacheContext((dust3d::MeshGenerator::GeneratedCacheContext*)m_generatedCacheContext);
if (!m_smoothNormal) { if (!m_smoothNormal) {
m_meshGenerator->setSmoothShadingThresholdAngleDegrees(0); m_meshGenerator->setSmoothShadingThresholdAngleDegrees(0);
} }
@ -880,16 +866,16 @@ void Document::generateTexture()
m_isTextureObsolete = true; m_isTextureObsolete = true;
return; return;
} }
qDebug() << "Texture guide generating.."; qDebug() << "Texture guide generating..";
emit textureGenerating(); emit textureGenerating();
m_isTextureObsolete = false; m_isTextureObsolete = false;
dust3d::Snapshot *snapshot = new dust3d::Snapshot; dust3d::Snapshot* snapshot = new dust3d::Snapshot;
toSnapshot(snapshot); toSnapshot(snapshot);
QThread *thread = new QThread; QThread* thread = new QThread;
m_textureGenerator = new TextureGenerator(*m_postProcessedObject, snapshot); m_textureGenerator = new TextureGenerator(*m_postProcessedObject, snapshot);
m_textureGenerator->moveToThread(thread); m_textureGenerator->moveToThread(thread);
connect(thread, &QThread::started, m_textureGenerator, &TextureGenerator::process); connect(thread, &QThread::started, m_textureGenerator, &TextureGenerator::process);
@ -906,21 +892,21 @@ void Document::textureReady()
updateTextureMetalnessImage(m_textureGenerator->takeResultTextureMetalnessImage()); updateTextureMetalnessImage(m_textureGenerator->takeResultTextureMetalnessImage());
updateTextureRoughnessImage(m_textureGenerator->takeResultTextureRoughnessImage()); updateTextureRoughnessImage(m_textureGenerator->takeResultTextureRoughnessImage());
updateTextureAmbientOcclusionImage(m_textureGenerator->takeResultTextureAmbientOcclusionImage()); updateTextureAmbientOcclusionImage(m_textureGenerator->takeResultTextureAmbientOcclusionImage());
delete m_resultTextureMesh; delete m_resultTextureMesh;
m_resultTextureMesh = m_textureGenerator->takeResultMesh(); m_resultTextureMesh = m_textureGenerator->takeResultMesh();
m_postProcessedObject->alphaEnabled = m_textureGenerator->hasTransparencySettings(); m_postProcessedObject->alphaEnabled = m_textureGenerator->hasTransparencySettings();
m_textureImageUpdateVersion++; m_textureImageUpdateVersion++;
delete m_textureGenerator; delete m_textureGenerator;
m_textureGenerator = nullptr; m_textureGenerator = nullptr;
qDebug() << "Texture guide generation done"; qDebug() << "Texture guide generation done";
emit resultTextureChanged(); emit resultTextureChanged();
if (m_isTextureObsolete) { if (m_isTextureObsolete) {
generateTexture(); generateTexture();
} else { } else {
@ -945,7 +931,7 @@ void Document::postProcess()
qDebug() << "Post processing.."; qDebug() << "Post processing..";
emit postProcessing(); emit postProcessing();
QThread *thread = new QThread; QThread* thread = new QThread;
m_postProcessor = new MeshResultPostProcessor(*m_currentObject); m_postProcessor = new MeshResultPostProcessor(*m_currentObject);
m_postProcessor->moveToThread(thread); m_postProcessor->moveToThread(thread);
connect(thread, &QThread::started, m_postProcessor, &MeshResultPostProcessor::process); connect(thread, &QThread::started, m_postProcessor, &MeshResultPostProcessor::process);
@ -972,7 +958,7 @@ void Document::postProcessedMeshResultReady()
} }
} }
const dust3d::Object &Document::currentPostProcessedObject() const const dust3d::Object& Document::currentPostProcessedObject() const
{ {
return *m_postProcessedObject; return *m_postProcessedObject;
} }
@ -1007,7 +993,7 @@ void Document::setPartSubdivState(dust3d::Uuid partId, bool subdived)
emit skeletonChanged(); emit skeletonChanged();
} }
void Document::resolveSnapshotBoundingBox(const dust3d::Snapshot &snapshot, QRectF *mainProfile, QRectF *sideProfile) void Document::resolveSnapshotBoundingBox(const dust3d::Snapshot& snapshot, QRectF* mainProfile, QRectF* sideProfile)
{ {
float left = 0; float left = 0;
bool leftFirstTime = true; bool leftFirstTime = true;
@ -1021,7 +1007,7 @@ void Document::resolveSnapshotBoundingBox(const dust3d::Snapshot &snapshot, QRec
bool zLeftFirstTime = true; bool zLeftFirstTime = true;
float zRight = 0; float zRight = 0;
bool zRightFirstTime = true; bool zRightFirstTime = true;
for (const auto &nodeIt: snapshot.nodes) { for (const auto& nodeIt : snapshot.nodes) {
float radius = dust3d::String::toFloat(dust3d::String::valueOrEmpty(nodeIt.second, "radius")); float radius = dust3d::String::toFloat(dust3d::String::valueOrEmpty(nodeIt.second, "radius"));
float x = dust3d::String::toFloat(dust3d::String::valueOrEmpty(nodeIt.second, "x")); float x = dust3d::String::toFloat(dust3d::String::valueOrEmpty(nodeIt.second, "x"));
float y = dust3d::String::toFloat(dust3d::String::valueOrEmpty(nodeIt.second, "y")); float y = dust3d::String::toFloat(dust3d::String::valueOrEmpty(nodeIt.second, "y"));
@ -1330,8 +1316,7 @@ void Document::setPartCutFaceLinkedId(dust3d::Uuid partId, dust3d::Uuid linkedId
qDebug() << "Part not found:" << partId; qDebug() << "Part not found:" << partId;
return; return;
} }
if (part->second.cutFace == dust3d::CutFace::UserDefined && if (part->second.cutFace == dust3d::CutFace::UserDefined && part->second.cutFaceLinkedId == linkedId)
part->second.cutFaceLinkedId == linkedId)
return; return;
part->second.setCutFaceLinkedId(linkedId); part->second.setCutFaceLinkedId(linkedId);
part->second.dirty = true; part->second.dirty = true;
@ -1370,7 +1355,7 @@ void Document::undo()
return; return;
m_redoItems.push_back(m_undoItems.back()); m_redoItems.push_back(m_undoItems.back());
m_undoItems.pop_back(); m_undoItems.pop_back();
const auto &item = m_undoItems.back(); const auto& item = m_undoItems.back();
fromSnapshot(item.snapshot); fromSnapshot(item.snapshot);
qDebug() << "Undo/Redo items:" << m_undoItems.size() << m_redoItems.size(); qDebug() << "Undo/Redo items:" << m_undoItems.size() << m_redoItems.size();
} }
@ -1380,7 +1365,7 @@ void Document::redo()
if (m_redoItems.empty()) if (m_redoItems.empty())
return; return;
m_undoItems.push_back(m_redoItems.back()); m_undoItems.push_back(m_redoItems.back());
const auto &item = m_redoItems.back(); const auto& item = m_redoItems.back();
fromSnapshot(item.snapshot); fromSnapshot(item.snapshot);
m_redoItems.pop_back(); m_redoItems.pop_back();
qDebug() << "Undo/Redo items:" << m_undoItems.size() << m_redoItems.size(); qDebug() << "Undo/Redo items:" << m_undoItems.size() << m_redoItems.size();
@ -1394,12 +1379,12 @@ void Document::clearHistories()
void Document::paste() void Document::paste()
{ {
const QClipboard *clipboard = QApplication::clipboard(); const QClipboard* clipboard = QApplication::clipboard();
const QMimeData *mimeData = clipboard->mimeData(); const QMimeData* mimeData = clipboard->mimeData();
if (mimeData->hasText()) { if (mimeData->hasText()) {
dust3d::Snapshot snapshot; dust3d::Snapshot snapshot;
std::string text = mimeData->text().toUtf8().constData(); std::string text = mimeData->text().toUtf8().constData();
loadSnapshotFromXmlString(&snapshot, (char *)text.c_str()); loadSnapshotFromXmlString(&snapshot, (char*)text.c_str());
addFromSnapshot(snapshot, SnapshotSource::Paste); addFromSnapshot(snapshot, SnapshotSource::Paste);
saveSnapshot(); saveSnapshot();
} }
@ -1407,8 +1392,8 @@ void Document::paste()
bool Document::hasPastableNodesInClipboard() const bool Document::hasPastableNodesInClipboard() const
{ {
const QClipboard *clipboard = QApplication::clipboard(); const QClipboard* clipboard = QApplication::clipboard();
const QMimeData *mimeData = clipboard->mimeData(); const QMimeData* mimeData = clipboard->mimeData();
if (mimeData->hasText()) { if (mimeData->hasText()) {
if (-1 != mimeData->text().indexOf("<node ")) if (-1 != mimeData->text().indexOf("<node "))
return true; return true;
@ -1418,8 +1403,8 @@ bool Document::hasPastableNodesInClipboard() const
bool Document::hasPastableMaterialsInClipboard() const bool Document::hasPastableMaterialsInClipboard() const
{ {
const QClipboard *clipboard = QApplication::clipboard(); const QClipboard* clipboard = QApplication::clipboard();
const QMimeData *mimeData = clipboard->mimeData(); const QMimeData* mimeData = clipboard->mimeData();
if (mimeData->hasText()) { if (mimeData->hasText()) {
if (-1 != mimeData->text().indexOf("<material ")) if (-1 != mimeData->text().indexOf("<material "))
return true; return true;
@ -1439,7 +1424,7 @@ bool Document::redoable() const
bool Document::isNodeEditable(dust3d::Uuid nodeId) const bool Document::isNodeEditable(dust3d::Uuid nodeId) const
{ {
const SkeletonNode *node = findNode(nodeId); const SkeletonNode* node = findNode(nodeId);
if (!node) { if (!node) {
qDebug() << "Node id not found:" << nodeId; qDebug() << "Node id not found:" << nodeId;
return false; return false;
@ -1449,7 +1434,7 @@ bool Document::isNodeEditable(dust3d::Uuid nodeId) const
bool Document::isEdgeEditable(dust3d::Uuid edgeId) const bool Document::isEdgeEditable(dust3d::Uuid edgeId) const
{ {
const SkeletonEdge *edge = findEdge(edgeId); const SkeletonEdge* edge = findEdge(edgeId);
if (!edge) { if (!edge) {
qDebug() << "Edge id not found:" << edgeId; qDebug() << "Edge id not found:" << edgeId;
return false; return false;
@ -1459,16 +1444,12 @@ bool Document::isEdgeEditable(dust3d::Uuid edgeId) const
bool Document::isExportReady() const bool Document::isExportReady() const
{ {
if (m_meshGenerator || if (m_meshGenerator || m_textureGenerator || m_postProcessor)
m_textureGenerator ||
m_postProcessor)
return false; return false;
if (m_isResultMeshObsolete || if (m_isResultMeshObsolete || m_isTextureObsolete || m_isPostProcessResultObsolete)
m_isTextureObsolete ||
m_isPostProcessResultObsolete)
return false; return false;
return true; return true;
} }
@ -1485,17 +1466,17 @@ void Document::addMaterial(dust3d::Uuid materialId, QString name, std::vector<Ma
qDebug() << "Material already exist:" << materialId; qDebug() << "Material already exist:" << materialId;
return; return;
} }
dust3d::Uuid newMaterialId = materialId; dust3d::Uuid newMaterialId = materialId;
auto &material = materialMap[newMaterialId]; auto& material = materialMap[newMaterialId];
material.id = newMaterialId; material.id = newMaterialId;
material.name = name; material.name = name;
material.layers = layers; material.layers = layers;
material.dirty = true; material.dirty = true;
materialIdList.push_back(newMaterialId); materialIdList.push_back(newMaterialId);
emit materialAdded(newMaterialId); emit materialAdded(newMaterialId);
emit materialListChanged(); emit materialListChanged();
emit optionsChanged(); emit optionsChanged();
@ -1510,7 +1491,7 @@ void Document::removeMaterial(dust3d::Uuid materialId)
} }
materialIdList.erase(std::remove(materialIdList.begin(), materialIdList.end(), materialId), materialIdList.end()); materialIdList.erase(std::remove(materialIdList.begin(), materialIdList.end(), materialId), materialIdList.end());
materialMap.erase(findMaterialResult); materialMap.erase(findMaterialResult);
emit materialListChanged(); emit materialListChanged();
emit materialRemoved(materialId); emit materialRemoved(materialId);
emit optionsChanged(); emit optionsChanged();
@ -1539,7 +1520,7 @@ void Document::renameMaterial(dust3d::Uuid materialId, QString name)
} }
if (findMaterialResult->second.name == name) if (findMaterialResult->second.name == name)
return; return;
findMaterialResult->second.name = name; findMaterialResult->second.name = name;
emit materialNameChanged(materialId); emit materialNameChanged(materialId);
emit materialListChanged(); emit materialListChanged();
@ -1552,10 +1533,10 @@ void Document::generateMaterialPreviews()
return; return;
} }
QThread *thread = new QThread; QThread* thread = new QThread;
m_materialPreviewsGenerator = new MaterialPreviewsGenerator(); m_materialPreviewsGenerator = new MaterialPreviewsGenerator();
bool hasDirtyMaterial = false; bool hasDirtyMaterial = false;
for (auto &materialIt: materialMap) { for (auto& materialIt : materialMap) {
if (!materialIt.second.dirty) if (!materialIt.second.dirty)
continue; continue;
m_materialPreviewsGenerator->addMaterial(materialIt.first, materialIt.second.layers); m_materialPreviewsGenerator->addMaterial(materialIt.first, materialIt.second.layers);
@ -1568,9 +1549,9 @@ void Document::generateMaterialPreviews()
delete thread; delete thread;
return; return;
} }
qDebug() << "Material previews generating.."; qDebug() << "Material previews generating..";
m_materialPreviewsGenerator->moveToThread(thread); m_materialPreviewsGenerator->moveToThread(thread);
connect(thread, &QThread::started, m_materialPreviewsGenerator, &MaterialPreviewsGenerator::process); connect(thread, &QThread::started, m_materialPreviewsGenerator, &MaterialPreviewsGenerator::process);
connect(m_materialPreviewsGenerator, &MaterialPreviewsGenerator::finished, this, &Document::materialPreviewsReady); connect(m_materialPreviewsGenerator, &MaterialPreviewsGenerator::finished, this, &Document::materialPreviewsReady);
@ -1581,10 +1562,10 @@ void Document::generateMaterialPreviews()
void Document::materialPreviewsReady() void Document::materialPreviewsReady()
{ {
for (const auto &materialId: m_materialPreviewsGenerator->generatedPreviewMaterialIds()) { for (const auto& materialId : m_materialPreviewsGenerator->generatedPreviewMaterialIds()) {
auto material = materialMap.find(materialId); auto material = materialMap.find(materialId);
if (material != materialMap.end()) { if (material != materialMap.end()) {
ModelMesh *resultPartPreviewMesh = m_materialPreviewsGenerator->takePreview(materialId); ModelMesh* resultPartPreviewMesh = m_materialPreviewsGenerator->takePreview(materialId);
material->second.updatePreviewMesh(resultPartPreviewMesh); material->second.updatePreviewMesh(resultPartPreviewMesh);
emit materialPreviewChanged(materialId); emit materialPreviewChanged(materialId);
} }
@ -1592,9 +1573,9 @@ void Document::materialPreviewsReady()
delete m_materialPreviewsGenerator; delete m_materialPreviewsGenerator;
m_materialPreviewsGenerator = nullptr; m_materialPreviewsGenerator = nullptr;
qDebug() << "Material previews generation done"; qDebug() << "Material previews generation done";
generateMaterialPreviews(); generateMaterialPreviews();
} }
@ -1619,18 +1600,18 @@ void Document::copyNodes(std::set<dust3d::Uuid> nodeIdSet) const
toSnapshot(&snapshot, nodeIdSet, DocumentToSnapshotFor::Nodes); toSnapshot(&snapshot, nodeIdSet, DocumentToSnapshotFor::Nodes);
std::string snapshotXml; std::string snapshotXml;
dust3d::saveSnapshotToXmlString(snapshot, snapshotXml); dust3d::saveSnapshotToXmlString(snapshot, snapshotXml);
QClipboard *clipboard = QApplication::clipboard(); QClipboard* clipboard = QApplication::clipboard();
clipboard->setText(snapshotXml.c_str()); clipboard->setText(snapshotXml.c_str());
} }
void Document::collectCutFaceList(std::vector<QString> &cutFaces) const void Document::collectCutFaceList(std::vector<QString>& cutFaces) const
{ {
cutFaces.clear(); cutFaces.clear();
std::vector<dust3d::Uuid> cutFacePartIdList; std::vector<dust3d::Uuid> cutFacePartIdList;
std::set<dust3d::Uuid> cutFacePartIds; std::set<dust3d::Uuid> cutFacePartIds;
for (const auto &it: partMap) { for (const auto& it : partMap) {
if (dust3d::PartTarget::CutFace == it.second.target) { if (dust3d::PartTarget::CutFace == it.second.target) {
if (cutFacePartIds.find(it.first) != cutFacePartIds.end()) if (cutFacePartIds.find(it.first) != cutFacePartIds.end())
continue; continue;
@ -1644,16 +1625,16 @@ void Document::collectCutFaceList(std::vector<QString> &cutFaces) const
cutFacePartIdList.push_back(it.second.cutFaceLinkedId); cutFacePartIdList.push_back(it.second.cutFaceLinkedId);
} }
} }
// Sort cut face by center.x of front view // Sort cut face by center.x of front view
std::map<dust3d::Uuid, float> centerOffsetMap; std::map<dust3d::Uuid, float> centerOffsetMap;
for (const auto &partId: cutFacePartIdList) { for (const auto& partId : cutFacePartIdList) {
const SkeletonPart *part = findPart(partId); const SkeletonPart* part = findPart(partId);
if (nullptr == part) if (nullptr == part)
continue; continue;
float offsetSum = 0; float offsetSum = 0;
for (const auto &nodeId: part->nodeIds) { for (const auto& nodeId : part->nodeIds) {
const SkeletonNode *node = findNode(nodeId); const SkeletonNode* node = findNode(nodeId);
if (nullptr == node) if (nullptr == node)
continue; continue;
offsetSum += node->getX(); offsetSum += node->getX();
@ -1663,16 +1644,16 @@ void Document::collectCutFaceList(std::vector<QString> &cutFaces) const
centerOffsetMap[partId] = offsetSum / part->nodeIds.size(); centerOffsetMap[partId] = offsetSum / part->nodeIds.size();
} }
std::sort(cutFacePartIdList.begin(), cutFacePartIdList.end(), std::sort(cutFacePartIdList.begin(), cutFacePartIdList.end(),
[&](const dust3d::Uuid &firstPartId, const dust3d::Uuid &secondPartId) { [&](const dust3d::Uuid& firstPartId, const dust3d::Uuid& secondPartId) {
return centerOffsetMap[firstPartId] < centerOffsetMap[secondPartId]; return centerOffsetMap[firstPartId] < centerOffsetMap[secondPartId];
}); });
size_t cutFaceTypeCount = (size_t)dust3d::CutFace::UserDefined; size_t cutFaceTypeCount = (size_t)dust3d::CutFace::UserDefined;
for (size_t i = 0; i < (size_t)cutFaceTypeCount; ++i) { for (size_t i = 0; i < (size_t)cutFaceTypeCount; ++i) {
dust3d::CutFace cutFace = (dust3d::CutFace)i; dust3d::CutFace cutFace = (dust3d::CutFace)i;
cutFaces.push_back(QString(dust3d::CutFaceToString(cutFace).c_str())); cutFaces.push_back(QString(dust3d::CutFaceToString(cutFace).c_str()));
} }
for (const auto &it: cutFacePartIdList) for (const auto& it : cutFacePartIdList)
cutFaces.push_back(QString(it.toString().c_str())); cutFaces.push_back(QString(it.toString().c_str()));
} }

View File

@ -1,38 +1,36 @@
#ifndef DUST3D_APPLICATION_DOCUMENT_H_ #ifndef DUST3D_APPLICATION_DOCUMENT_H_
#define DUST3D_APPLICATION_DOCUMENT_H_ #define DUST3D_APPLICATION_DOCUMENT_H_
#include <QObject> #include "material_layer.h"
#include <vector>
#include <map>
#include <set>
#include <deque>
#include <QImage>
#include <cmath>
#include <algorithm>
#include <QPolygon>
#include <dust3d/base/uuid.h>
#include <dust3d/base/snapshot.h>
#include <dust3d/base/texture_type.h>
#include <dust3d/base/combine_mode.h>
#include "model_mesh.h" #include "model_mesh.h"
#include "monochrome_mesh.h" #include "monochrome_mesh.h"
#include "theme.h"
#include "skeleton_document.h" #include "skeleton_document.h"
#include "material_layer.h" #include "theme.h"
#include <QImage>
#include <QObject>
#include <QPolygon>
#include <algorithm>
#include <cmath>
#include <deque>
#include <dust3d/base/combine_mode.h>
#include <dust3d/base/snapshot.h>
#include <dust3d/base/texture_type.h>
#include <dust3d/base/uuid.h>
#include <map>
#include <set>
#include <vector>
class MaterialPreviewsGenerator; class MaterialPreviewsGenerator;
class TextureGenerator; class TextureGenerator;
class MeshGenerator; class MeshGenerator;
class MeshResultPostProcessor; class MeshResultPostProcessor;
class HistoryItem class HistoryItem {
{
public: public:
dust3d::Snapshot snapshot; dust3d::Snapshot snapshot;
}; };
class Material class Material {
{
public: public:
Material() Material()
{ {
@ -45,31 +43,30 @@ public:
QString name; QString name;
bool dirty = true; bool dirty = true;
std::vector<MaterialLayer> layers; std::vector<MaterialLayer> layers;
void updatePreviewMesh(ModelMesh *previewMesh) void updatePreviewMesh(ModelMesh* previewMesh)
{ {
delete m_previewMesh; delete m_previewMesh;
m_previewMesh = previewMesh; m_previewMesh = previewMesh;
} }
ModelMesh *takePreviewMesh() const ModelMesh* takePreviewMesh() const
{ {
if (nullptr == m_previewMesh) if (nullptr == m_previewMesh)
return nullptr; return nullptr;
return new ModelMesh(*m_previewMesh); return new ModelMesh(*m_previewMesh);
} }
private: private:
Q_DISABLE_COPY(Material); Q_DISABLE_COPY(Material);
ModelMesh *m_previewMesh = nullptr; ModelMesh* m_previewMesh = nullptr;
}; };
enum class DocumentToSnapshotFor enum class DocumentToSnapshotFor {
{
Document = 0, Document = 0,
Nodes, Nodes,
Materials Materials
}; };
class Document : public SkeletonDocument class Document : public SkeletonDocument {
{
Q_OBJECT Q_OBJECT
signals: signals:
void nodeCutRotationChanged(dust3d::Uuid nodeId); void nodeCutRotationChanged(dust3d::Uuid nodeId);
@ -121,26 +118,28 @@ signals:
void postProcessing(); void postProcessing();
void textureGenerating(); void textureGenerating();
void textureChanged(); void textureChanged();
public: // need initialize public: // need initialize
QImage *textureImage = nullptr; QImage* textureImage = nullptr;
QByteArray *textureImageByteArray = nullptr; QByteArray* textureImageByteArray = nullptr;
QImage *textureNormalImage = nullptr; QImage* textureNormalImage = nullptr;
QByteArray *textureNormalImageByteArray = nullptr; QByteArray* textureNormalImageByteArray = nullptr;
QImage *textureMetalnessImage = nullptr; QImage* textureMetalnessImage = nullptr;
QByteArray *textureMetalnessImageByteArray = nullptr; QByteArray* textureMetalnessImageByteArray = nullptr;
QImage *textureRoughnessImage = nullptr; QImage* textureRoughnessImage = nullptr;
QByteArray *textureRoughnessImageByteArray = nullptr; QByteArray* textureRoughnessImageByteArray = nullptr;
QImage *textureAmbientOcclusionImage = nullptr; QImage* textureAmbientOcclusionImage = nullptr;
QByteArray *textureAmbientOcclusionImageByteArray = nullptr; QByteArray* textureAmbientOcclusionImageByteArray = nullptr;
bool weldEnabled = true; bool weldEnabled = true;
float brushMetalness = ModelMesh::m_defaultMetalness; float brushMetalness = ModelMesh::m_defaultMetalness;
float brushRoughness = ModelMesh::m_defaultRoughness; float brushRoughness = ModelMesh::m_defaultRoughness;
public: public:
Document(); Document();
~Document(); ~Document();
std::map<dust3d::Uuid, Material> materialMap; std::map<dust3d::Uuid, Material> materialMap;
std::vector<dust3d::Uuid> materialIdList; std::vector<dust3d::Uuid> materialIdList;
bool undoable() const override; bool undoable() const override;
bool redoable() const override; bool redoable() const override;
bool hasPastableNodesInClipboard() const override; bool hasPastableNodesInClipboard() const override;
@ -148,39 +147,38 @@ public:
bool isNodeEditable(dust3d::Uuid nodeId) const override; bool isNodeEditable(dust3d::Uuid nodeId) const override;
bool isEdgeEditable(dust3d::Uuid edgeId) const override; bool isEdgeEditable(dust3d::Uuid edgeId) const override;
void copyNodes(std::set<dust3d::Uuid> nodeIdSet) const override; void copyNodes(std::set<dust3d::Uuid> nodeIdSet) const override;
void toSnapshot(dust3d::Snapshot *snapshot, const std::set<dust3d::Uuid> &limitNodeIds=std::set<dust3d::Uuid>(), void toSnapshot(dust3d::Snapshot* snapshot, const std::set<dust3d::Uuid>& limitNodeIds = std::set<dust3d::Uuid>(),
DocumentToSnapshotFor forWhat=DocumentToSnapshotFor::Document, DocumentToSnapshotFor forWhat = DocumentToSnapshotFor::Document,
const std::set<dust3d::Uuid> &limitMaterialIds=std::set<dust3d::Uuid>()) const; const std::set<dust3d::Uuid>& limitMaterialIds = std::set<dust3d::Uuid>()) const;
void fromSnapshot(const dust3d::Snapshot &snapshot); void fromSnapshot(const dust3d::Snapshot& snapshot);
enum class SnapshotSource enum class SnapshotSource {
{
Unknown, Unknown,
Paste, Paste,
Import Import
}; };
void addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSource source=SnapshotSource::Paste); void addFromSnapshot(const dust3d::Snapshot& snapshot, enum SnapshotSource source = SnapshotSource::Paste);
const Material *findMaterial(dust3d::Uuid materialId) const; const Material* findMaterial(dust3d::Uuid materialId) const;
ModelMesh *takeResultMesh(); ModelMesh* takeResultMesh();
MonochromeMesh *takeWireframeMesh(); MonochromeMesh* takeWireframeMesh();
ModelMesh *takePaintedMesh(); ModelMesh* takePaintedMesh();
bool isMeshGenerationSucceed(); bool isMeshGenerationSucceed();
ModelMesh *takeResultTextureMesh(); ModelMesh* takeResultTextureMesh();
ModelMesh *takeResultRigWeightMesh(); ModelMesh* takeResultRigWeightMesh();
void updateTurnaround(const QImage &image); void updateTurnaround(const QImage& image);
void clearTurnaround(); void clearTurnaround();
void updateTextureImage(QImage *image); void updateTextureImage(QImage* image);
void updateTextureNormalImage(QImage *image); void updateTextureNormalImage(QImage* image);
void updateTextureMetalnessImage(QImage *image); void updateTextureMetalnessImage(QImage* image);
void updateTextureRoughnessImage(QImage *image); void updateTextureRoughnessImage(QImage* image);
void updateTextureAmbientOcclusionImage(QImage *image); void updateTextureAmbientOcclusionImage(QImage* image);
bool hasPastableMaterialsInClipboard() const; bool hasPastableMaterialsInClipboard() const;
const dust3d::Object &currentPostProcessedObject() const; const dust3d::Object& currentPostProcessedObject() const;
bool isExportReady() const; bool isExportReady() const;
bool isPostProcessResultObsolete() const; bool isPostProcessResultObsolete() const;
bool isMeshGenerating() const; bool isMeshGenerating() const;
bool isPostProcessing() const; bool isPostProcessing() const;
bool isTextureGenerating() const; bool isTextureGenerating() const;
void collectCutFaceList(std::vector<QString> &cutFaces) const; void collectCutFaceList(std::vector<QString>& cutFaces) const;
public slots: public slots:
void undo() override; void undo() override;
void redo() override; void redo() override;
@ -233,30 +231,32 @@ public slots:
void removeMaterial(dust3d::Uuid materialId); void removeMaterial(dust3d::Uuid materialId);
void setMaterialLayers(dust3d::Uuid materialId, std::vector<MaterialLayer> layers); void setMaterialLayers(dust3d::Uuid materialId, std::vector<MaterialLayer> layers);
void renameMaterial(dust3d::Uuid materialId, QString name); void renameMaterial(dust3d::Uuid materialId, QString name);
private: private:
void resolveSnapshotBoundingBox(const dust3d::Snapshot &snapshot, QRectF *mainProfile, QRectF *sideProfile); void resolveSnapshotBoundingBox(const dust3d::Snapshot& snapshot, QRectF* mainProfile, QRectF* sideProfile);
void settleOrigin(); void settleOrigin();
void checkExportReadyState(); void checkExportReadyState();
bool m_isResultMeshObsolete = false; bool m_isResultMeshObsolete = false;
MeshGenerator *m_meshGenerator = nullptr; MeshGenerator* m_meshGenerator = nullptr;
ModelMesh *m_resultMesh = nullptr; ModelMesh* m_resultMesh = nullptr;
std::unique_ptr<MonochromeMesh> m_wireframeMesh; std::unique_ptr<MonochromeMesh> m_wireframeMesh;
bool m_isMeshGenerationSucceed = true; bool m_isMeshGenerationSucceed = true;
int m_batchChangeRefCount = 0; int m_batchChangeRefCount = 0;
dust3d::Object *m_currentObject = nullptr; dust3d::Object* m_currentObject = nullptr;
bool m_isTextureObsolete = false; bool m_isTextureObsolete = false;
TextureGenerator *m_textureGenerator = nullptr; TextureGenerator* m_textureGenerator = nullptr;
bool m_isPostProcessResultObsolete = false; bool m_isPostProcessResultObsolete = false;
MeshResultPostProcessor *m_postProcessor = nullptr; MeshResultPostProcessor* m_postProcessor = nullptr;
dust3d::Object *m_postProcessedObject = new dust3d::Object; dust3d::Object* m_postProcessedObject = new dust3d::Object;
ModelMesh *m_resultTextureMesh = nullptr; ModelMesh* m_resultTextureMesh = nullptr;
unsigned long long m_textureImageUpdateVersion = 0; unsigned long long m_textureImageUpdateVersion = 0;
bool m_smoothNormal = false; bool m_smoothNormal = false;
MaterialPreviewsGenerator *m_materialPreviewsGenerator = nullptr; MaterialPreviewsGenerator* m_materialPreviewsGenerator = nullptr;
quint64 m_meshGenerationId = 0; quint64 m_meshGenerationId = 0;
quint64 m_nextMeshGenerationId = 0; quint64 m_nextMeshGenerationId = 0;
void *m_generatedCacheContext = nullptr; void* m_generatedCacheContext = nullptr;
private: private:
static unsigned long m_maxSnapshot; static unsigned long m_maxSnapshot;
std::deque<HistoryItem> m_undoItems; std::deque<HistoryItem> m_undoItems;

View File

@ -1,17 +1,17 @@
#include <set> #include "document_saver.h"
#include "image_forever.h"
#include <QGuiApplication> #include <QGuiApplication>
#include <QtCore/qbuffer.h> #include <QtCore/qbuffer.h>
#include <dust3d/base/ds3_file.h> #include <dust3d/base/ds3_file.h>
#include <dust3d/base/snapshot_xml.h> #include <dust3d/base/snapshot_xml.h>
#include "document_saver.h" #include <set>
#include "image_forever.h"
DocumentSaver::DocumentSaver(const QString *filename, DocumentSaver::DocumentSaver(const QString* filename,
dust3d::Snapshot *snapshot, dust3d::Snapshot* snapshot,
QByteArray *turnaroundPngByteArray) : QByteArray* turnaroundPngByteArray)
m_filename(filename), : m_filename(filename)
m_snapshot(snapshot), , m_snapshot(snapshot)
m_turnaroundPngByteArray(turnaroundPngByteArray) , m_turnaroundPngByteArray(turnaroundPngByteArray)
{ {
} }
@ -29,12 +29,12 @@ void DocumentSaver::process()
emit finished(); emit finished();
} }
void DocumentSaver::collectUsedResourceIds(const dust3d::Snapshot *snapshot, void DocumentSaver::collectUsedResourceIds(const dust3d::Snapshot* snapshot,
std::set<dust3d::Uuid> &imageIds) std::set<dust3d::Uuid>& imageIds)
{ {
for (const auto &material: snapshot->materials) { for (const auto& material : snapshot->materials) {
for (auto &layer: material.second) { for (auto& layer : material.second) {
for (auto &mapItem: layer.second) { for (auto& mapItem : layer.second) {
auto findImageIdString = mapItem.find("linkData"); auto findImageIdString = mapItem.find("linkData");
if (findImageIdString == mapItem.end()) if (findImageIdString == mapItem.end())
continue; continue;
@ -45,12 +45,12 @@ void DocumentSaver::collectUsedResourceIds(const dust3d::Snapshot *snapshot,
} }
} }
bool DocumentSaver::save(const QString *filename, bool DocumentSaver::save(const QString* filename,
dust3d::Snapshot *snapshot, dust3d::Snapshot* snapshot,
const QByteArray *turnaroundPngByteArray) const QByteArray* turnaroundPngByteArray)
{ {
dust3d::Ds3FileWriter ds3Writer; dust3d::Ds3FileWriter ds3Writer;
{ {
std::string modelXml; std::string modelXml;
saveSnapshotToXmlString(*snapshot, modelXml); saveSnapshotToXmlString(*snapshot, modelXml);
@ -58,20 +58,20 @@ bool DocumentSaver::save(const QString *filename,
ds3Writer.add("model.xml", "model", modelXml.c_str(), modelXml.size()); ds3Writer.add("model.xml", "model", modelXml.c_str(), modelXml.size());
} }
} }
if (nullptr != turnaroundPngByteArray && turnaroundPngByteArray->size() > 0) if (nullptr != turnaroundPngByteArray && turnaroundPngByteArray->size() > 0)
ds3Writer.add("canvas.png", "asset", turnaroundPngByteArray->data(), turnaroundPngByteArray->size()); ds3Writer.add("canvas.png", "asset", turnaroundPngByteArray->data(), turnaroundPngByteArray->size());
std::set<dust3d::Uuid> imageIds; std::set<dust3d::Uuid> imageIds;
collectUsedResourceIds(snapshot, imageIds); collectUsedResourceIds(snapshot, imageIds);
for (const auto &imageId: imageIds) { for (const auto& imageId : imageIds) {
const QByteArray *pngByteArray = ImageForever::getPngByteArray(imageId); const QByteArray* pngByteArray = ImageForever::getPngByteArray(imageId);
if (nullptr == pngByteArray) if (nullptr == pngByteArray)
continue; continue;
if (pngByteArray->size() > 0) if (pngByteArray->size() > 0)
ds3Writer.add("images/" + imageId.toString() + ".png", "asset", pngByteArray->data(), pngByteArray->size()); ds3Writer.add("images/" + imageId.toString() + ".png", "asset", pngByteArray->data(), pngByteArray->size());
} }
return ds3Writer.save(filename->toUtf8().constData()); return ds3Writer.save(filename->toUtf8().constData());
} }

View File

@ -1,35 +1,35 @@
#ifndef DUST3D_APPLICATION_DOCUMENT_SAVER_H_ #ifndef DUST3D_APPLICATION_DOCUMENT_SAVER_H_
#define DUST3D_APPLICATION_DOCUMENT_SAVER_H_ #define DUST3D_APPLICATION_DOCUMENT_SAVER_H_
#include <QString>
#include <QObject>
#include <QByteArray> #include <QByteArray>
#include <QObject>
#include <QString>
#include <dust3d/base/snapshot.h>
#include <dust3d/base/uuid.h>
#include <map> #include <map>
#include <set> #include <set>
#include <dust3d/base/uuid.h>
#include <dust3d/base/snapshot.h>
class DocumentSaver : public QObject class DocumentSaver : public QObject {
{
Q_OBJECT Q_OBJECT
public: public:
DocumentSaver(const QString *filename, DocumentSaver(const QString* filename,
dust3d::Snapshot *snapshot, dust3d::Snapshot* snapshot,
QByteArray *turnaroundPngByteArray); QByteArray* turnaroundPngByteArray);
~DocumentSaver(); ~DocumentSaver();
static bool save(const QString *filename, static bool save(const QString* filename,
dust3d::Snapshot *snapshot, dust3d::Snapshot* snapshot,
const QByteArray *turnaroundPngByteArray); const QByteArray* turnaroundPngByteArray);
static void collectUsedResourceIds(const dust3d::Snapshot *snapshot, static void collectUsedResourceIds(const dust3d::Snapshot* snapshot,
std::set<dust3d::Uuid> &imageIds); std::set<dust3d::Uuid>& imageIds);
signals: signals:
void finished(); void finished();
public slots: public slots:
void process(); void process();
private: private:
const QString *m_filename = nullptr; const QString* m_filename = nullptr;
dust3d::Snapshot *m_snapshot = nullptr; dust3d::Snapshot* m_snapshot = nullptr;
QByteArray *m_turnaroundPngByteArray = nullptr; QByteArray* m_turnaroundPngByteArray = nullptr;
}; };
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -1,21 +1,21 @@
#ifndef DUST3D_APPLICATION_DOCUMENT_WINDOW_H_ #ifndef DUST3D_APPLICATION_DOCUMENT_WINDOW_H_
#define DUST3D_APPLICATION_DOCUMENT_WINDOW_H_ #define DUST3D_APPLICATION_DOCUMENT_WINDOW_H_
#include <memory> #include "component_preview_images_decorator.h"
#include <QMainWindow>
#include <QShowEvent>
#include <QPushButton>
#include <QString>
#include <QMenu>
#include <QAction>
#include <map>
#include <QStringList>
#include <QLabel>
#include <QShortcut>
#include "model_widget.h"
#include "graphics_container_widget.h" #include "graphics_container_widget.h"
#include "mesh_preview_images_generator.h" #include "mesh_preview_images_generator.h"
#include "component_preview_images_decorator.h" #include "model_widget.h"
#include <QAction>
#include <QLabel>
#include <QMainWindow>
#include <QMenu>
#include <QPushButton>
#include <QShortcut>
#include <QShowEvent>
#include <QString>
#include <QStringList>
#include <map>
#include <memory>
class Document; class Document;
class SkeletonGraphicsWidget; class SkeletonGraphicsWidget;
@ -23,38 +23,39 @@ class PartManageWidget;
class ToolbarButton; class ToolbarButton;
class SpinnableToolbarIcon; class SpinnableToolbarIcon;
class DocumentWindow : public QMainWindow class DocumentWindow : public QMainWindow {
{
Q_OBJECT Q_OBJECT
signals: signals:
void initialized(); void initialized();
void uninialized(); void uninialized();
void waitingExportFinished(const QString &filename, bool isSuccessful); void waitingExportFinished(const QString& filename, bool isSuccessful);
void workingStatusChanged(bool isWorking); void workingStatusChanged(bool isWorking);
public: public:
DocumentWindow(); DocumentWindow();
~DocumentWindow(); ~DocumentWindow();
Document *document(); Document* document();
ModelWidget *modelWidget(); ModelWidget* modelWidget();
bool isWorking(); bool isWorking();
static DocumentWindow *createDocumentWindow(); static DocumentWindow* createDocumentWindow();
static const std::map<DocumentWindow *, dust3d::Uuid> &documentWindows(); static const std::map<DocumentWindow*, dust3d::Uuid>& documentWindows();
static void showAcknowlegements(); static void showAcknowlegements();
static void showContributors(); static void showContributors();
static void showSupporters(); static void showSupporters();
static void showAbout(); static void showAbout();
static size_t total(); static size_t total();
protected: protected:
void showEvent(QShowEvent *event); void showEvent(QShowEvent* event);
void closeEvent(QCloseEvent *event); void closeEvent(QCloseEvent* event);
void mousePressEvent(QMouseEvent *event); void mousePressEvent(QMouseEvent* event);
public slots: public slots:
void changeTurnaround(); void changeTurnaround();
void save(); void save();
void saveTo(const QString &saveAsFilename); void saveTo(const QString& saveAsFilename);
void open(); void open();
void openExample(const QString &modelName); void openExample(const QString& modelName);
void openPathAs(const QString &path, const QString &asName); void openPathAs(const QString& path, const QString& asName);
void exportObjResult(); void exportObjResult();
void exportGlbResult(); void exportGlbResult();
void exportFbxResult(); void exportFbxResult();
@ -76,13 +77,13 @@ public slots:
void updateYlockButtonState(); void updateYlockButtonState();
void updateZlockButtonState(); void updateZlockButtonState();
void updateRadiusLockButtonState(); void updateRadiusLockButtonState();
void registerDialog(QWidget *widget); void registerDialog(QWidget* widget);
void unregisterDialog(QWidget *widget); void unregisterDialog(QWidget* widget);
void setExportWaitingList(const QStringList &filenames); void setExportWaitingList(const QStringList& filenames);
void checkExportWaitingList(); void checkExportWaitingList();
void exportObjToFilename(const QString &filename); void exportObjToFilename(const QString& filename);
void exportFbxToFilename(const QString &filename); void exportFbxToFilename(const QString& filename);
void exportGlbToFilename(const QString &filename); void exportGlbToFilename(const QString& filename);
void toggleRotation(); void toggleRotation();
void generateComponentPreviewImages(); void generateComponentPreviewImages();
void componentPreviewImagesReady(); void componentPreviewImagesReady();
@ -92,88 +93,88 @@ public slots:
void openRecentFile(); void openRecentFile();
void updateRecentFileActions(); void updateRecentFileActions();
void toggleRenderColor(); void toggleRenderColor();
private: private:
void setCurrentFilename(const QString &filename); void setCurrentFilename(const QString& filename);
void updateTitle(); void updateTitle();
void initializeShortcuts(); void initializeShortcuts();
void initializeToolShortcuts(SkeletonGraphicsWidget *graphicsWidget); void initializeToolShortcuts(SkeletonGraphicsWidget* graphicsWidget);
void initializeCanvasShortcuts(SkeletonGraphicsWidget *graphicsWidget); void initializeCanvasShortcuts(SkeletonGraphicsWidget* graphicsWidget);
QShortcut *createShortcut(QKeySequence key); QShortcut* createShortcut(QKeySequence key);
QString strippedName(const QString &fullFileName); QString strippedName(const QString& fullFileName);
bool openFiles(const QStringList &pathList); bool openFiles(const QStringList& pathList);
Document *m_document = nullptr; Document* m_document = nullptr;
bool m_firstShow = true; bool m_firstShow = true;
bool m_documentSaved = true; bool m_documentSaved = true;
std::vector<QWidget *> m_dialogs; std::vector<QWidget*> m_dialogs;
bool m_isLastMeshGenerationSucceed = true; bool m_isLastMeshGenerationSucceed = true;
quint64 m_currentUpdatedMeshId = 0; quint64 m_currentUpdatedMeshId = 0;
QStringList m_waitingForExportToFilenames; QStringList m_waitingForExportToFilenames;
QString m_currentFilename;
ModelWidget *m_modelRenderWidget = nullptr;
SkeletonGraphicsWidget *m_canvasGraphicsWidget = nullptr;
GraphicsContainerWidget *m_graphicsContainerWidget = nullptr;
QMenu *m_fileMenu = nullptr;
QAction *m_newWindowAction = nullptr;
QAction *m_newDocumentAction = nullptr;
QAction *m_openAction = nullptr;
QMenu *m_openExampleMenu = nullptr;
QAction *m_saveAction = nullptr;
QAction *m_saveAsAction = nullptr;
QAction *m_saveAllAction = nullptr;
QAction *m_changeTurnaroundAction = nullptr;
std::vector<QAction *> m_recentFileActions;
QAction *m_recentFileSeparatorAction = nullptr;
QAction *m_quitAction = nullptr;
QAction *m_exportAsObjAction = nullptr; QString m_currentFilename;
QAction *m_exportAsGlbAction = nullptr;
QAction *m_exportAsFbxAction = nullptr; ModelWidget* m_modelRenderWidget = nullptr;
SkeletonGraphicsWidget* m_canvasGraphicsWidget = nullptr;
QMenu *m_viewMenu = nullptr; GraphicsContainerWidget* m_graphicsContainerWidget = nullptr;
QAction *m_toggleWireframeAction = nullptr;
QAction *m_toggleRotationAction = nullptr; QMenu* m_fileMenu = nullptr;
QAction *m_toggleColorAction = nullptr; QAction* m_newWindowAction = nullptr;
QAction* m_newDocumentAction = nullptr;
QAction* m_openAction = nullptr;
QMenu* m_openExampleMenu = nullptr;
QAction* m_saveAction = nullptr;
QAction* m_saveAsAction = nullptr;
QAction* m_saveAllAction = nullptr;
QAction* m_changeTurnaroundAction = nullptr;
std::vector<QAction*> m_recentFileActions;
QAction* m_recentFileSeparatorAction = nullptr;
QAction* m_quitAction = nullptr;
QAction* m_exportAsObjAction = nullptr;
QAction* m_exportAsGlbAction = nullptr;
QAction* m_exportAsFbxAction = nullptr;
QMenu* m_viewMenu = nullptr;
QAction* m_toggleWireframeAction = nullptr;
QAction* m_toggleRotationAction = nullptr;
QAction* m_toggleColorAction = nullptr;
bool m_modelRemoveColor = false; bool m_modelRemoveColor = false;
QMenu *m_windowMenu = nullptr; QMenu* m_windowMenu = nullptr;
QAction *m_showPartsListAction = nullptr; QAction* m_showPartsListAction = nullptr;
QAction *m_showDebugDialogAction = nullptr; QAction* m_showDebugDialogAction = nullptr;
QAction *m_showMaterialsAction = nullptr; QAction* m_showMaterialsAction = nullptr;
QMenu *m_helpMenu = nullptr; QMenu* m_helpMenu = nullptr;
QAction *m_gotoHomepageAction = nullptr; QAction* m_gotoHomepageAction = nullptr;
QAction *m_viewSourceAction = nullptr; QAction* m_viewSourceAction = nullptr;
QAction *m_aboutAction = nullptr; QAction* m_aboutAction = nullptr;
QAction *m_checkForUpdatesAction = nullptr; QAction* m_checkForUpdatesAction = nullptr;
QAction *m_reportIssuesAction = nullptr; QAction* m_reportIssuesAction = nullptr;
QAction *m_seeContributorsAction = nullptr; QAction* m_seeContributorsAction = nullptr;
QAction *m_seeSupportersAction = nullptr; QAction* m_seeSupportersAction = nullptr;
QAction *m_seeAcknowlegementsAction = nullptr; QAction* m_seeAcknowlegementsAction = nullptr;
QAction *m_seeReferenceGuideAction = nullptr; QAction* m_seeReferenceGuideAction = nullptr;
ToolbarButton *m_xLockButton = nullptr; ToolbarButton* m_xLockButton = nullptr;
ToolbarButton *m_yLockButton = nullptr; ToolbarButton* m_yLockButton = nullptr;
ToolbarButton *m_zLockButton = nullptr; ToolbarButton* m_zLockButton = nullptr;
ToolbarButton *m_radiusLockButton = nullptr; ToolbarButton* m_radiusLockButton = nullptr;
QMetaObject::Connection m_partListDockerVisibleSwitchConnection; QMetaObject::Connection m_partListDockerVisibleSwitchConnection;
MeshPreviewImagesGenerator *m_componentPreviewImagesGenerator = nullptr; MeshPreviewImagesGenerator* m_componentPreviewImagesGenerator = nullptr;
bool m_isComponentPreviewImagesObsolete = false; bool m_isComponentPreviewImagesObsolete = false;
std::unique_ptr<ComponentPreviewImagesDecorator> m_componentPreviewImagesDecorator; std::unique_ptr<ComponentPreviewImagesDecorator> m_componentPreviewImagesDecorator;
bool m_isComponentPreviewImageDecorationsObsolete = false; bool m_isComponentPreviewImageDecorationsObsolete = false;
PartManageWidget *m_partManageWidget = nullptr; PartManageWidget* m_partManageWidget = nullptr;
SpinnableToolbarIcon *m_inprogressIndicator = nullptr; SpinnableToolbarIcon* m_inprogressIndicator = nullptr;
std::map<QKeySequence, QShortcut *> m_shortcutMap; std::map<QKeySequence, QShortcut*> m_shortcutMap;
}; };
#endif #endif

View File

@ -1,13 +1,13 @@
#include "fbx_file.h"
#include "document.h"
#include "version.h"
#include <QByteArray>
#include <QDateTime>
#include <QFileInfo>
#include <QtCore/qbuffer.h>
#include <QtMath>
#include <fbxnode.h> #include <fbxnode.h>
#include <fbxproperty.h> #include <fbxproperty.h>
#include <QDateTime>
#include <QtMath>
#include <QtCore/qbuffer.h>
#include <QByteArray>
#include <QFileInfo>
#include "fbx_file.h"
#include "version.h"
#include "document.h"
using namespace fbx; using namespace fbx;
@ -27,9 +27,9 @@ void FbxFileWriter::createFbxHeader()
headerExtension.addPropertyNode("EncryptionType", (int32_t)0); headerExtension.addPropertyNode("EncryptionType", (int32_t)0);
{ {
auto currentDateTime = QDateTime::currentDateTime(); auto currentDateTime = QDateTime::currentDateTime();
const auto &currentDate = currentDateTime.date(); const auto& currentDate = currentDateTime.date();
const auto &currentTime = currentDateTime.time(); const auto& currentTime = currentDateTime.time();
FBXNode creationTimeStamp("CreationTimeStamp"); FBXNode creationTimeStamp("CreationTimeStamp");
creationTimeStamp.addPropertyNode("Version", (int32_t)1000); creationTimeStamp.addPropertyNode("Version", (int32_t)1000);
creationTimeStamp.addPropertyNode("Year", (int32_t)currentDate.year()); creationTimeStamp.addPropertyNode("Year", (int32_t)currentDate.year());
@ -45,7 +45,7 @@ void FbxFileWriter::createFbxHeader()
headerExtension.addPropertyNode("Creator", APP_NAME " " APP_HUMAN_VER); headerExtension.addPropertyNode("Creator", APP_NAME " " APP_HUMAN_VER);
{ {
FBXNode sceneInfo("SceneInfo"); FBXNode sceneInfo("SceneInfo");
sceneInfo.addProperty(std::vector<uint8_t>({'G','l','o','b','a','l','I','n','f','o',0,1,'S','c','e','n','e','I','n','f','o'}), 'S'); sceneInfo.addProperty(std::vector<uint8_t>({ 'G', 'l', 'o', 'b', 'a', 'l', 'I', 'n', 'f', 'o', 0, 1, 'S', 'c', 'e', 'n', 'e', 'I', 'n', 'f', 'o' }), 'S');
sceneInfo.addProperty("UserData"); sceneInfo.addProperty("UserData");
sceneInfo.addPropertyNode("Type", "UserData"); sceneInfo.addPropertyNode("Type", "UserData");
sceneInfo.addPropertyNode("Version", 100); sceneInfo.addPropertyNode("Version", 100);
@ -185,7 +185,7 @@ void FbxFileWriter::createFbxHeader()
headerExtension.addChild(sceneInfo); headerExtension.addChild(sceneInfo);
headerExtension.addChild(FBXNode()); headerExtension.addChild(FBXNode());
} }
m_fbxDocument.nodes.push_back(headerExtension); m_fbxDocument.nodes.push_back(headerExtension);
} }
@ -198,7 +198,7 @@ void FbxFileWriter::createCreationTime()
void FbxFileWriter::createFileId() void FbxFileWriter::createFileId()
{ {
std::vector<uint8_t> fileIdBytes = {40, (uint8_t)-77, 42, (uint8_t)-21, (uint8_t)-74, 36, (uint8_t)-52, (uint8_t)-62, (uint8_t)-65, (uint8_t)-56, (uint8_t)-80, 42, (uint8_t)-87, 43, (uint8_t)-4, (uint8_t)-15}; std::vector<uint8_t> fileIdBytes = { 40, (uint8_t)-77, 42, (uint8_t)-21, (uint8_t)-74, 36, (uint8_t)-52, (uint8_t)-62, (uint8_t)-65, (uint8_t)-56, (uint8_t)-80, 42, (uint8_t)-87, 43, (uint8_t)-4, (uint8_t)-15 };
FBXNode fileId("FileId"); FBXNode fileId("FileId");
fileId.addProperty(fileIdBytes, 'R'); fileId.addProperty(fileIdBytes, 'R');
m_fbxDocument.nodes.push_back(fileId); m_fbxDocument.nodes.push_back(fileId);
@ -415,13 +415,13 @@ void FbxFileWriter::createReferences()
} }
void FbxFileWriter::createDefinitions(size_t deformerCount, void FbxFileWriter::createDefinitions(size_t deformerCount,
size_t textureCount, size_t textureCount,
size_t videoCount, size_t videoCount,
bool hasAnimtion, bool hasAnimtion,
size_t animationStackCount, size_t animationStackCount,
size_t animationLayerCount, size_t animationLayerCount,
size_t animationCurveNodeCount, size_t animationCurveNodeCount,
size_t animationCurveCount) size_t animationCurveCount)
{ {
FBXNode definitions("Definitions"); FBXNode definitions("Definitions");
definitions.addPropertyNode("Version", (int32_t)100); definitions.addPropertyNode("Version", (int32_t)100);
@ -2198,15 +2198,15 @@ void FbxFileWriter::createDefinitions(size_t deformerCount,
m_fbxDocument.nodes.push_back(definitions); m_fbxDocument.nodes.push_back(definitions);
} }
FbxFileWriter::FbxFileWriter(dust3d::Object &object, FbxFileWriter::FbxFileWriter(dust3d::Object& object,
const QString &filename, const QString& filename,
QImage *textureImage, QImage* textureImage,
QImage *normalImage, QImage* normalImage,
QImage *metalnessImage, QImage* metalnessImage,
QImage *roughnessImage, QImage* roughnessImage,
QImage *ambientOcclusionImage) : QImage* ambientOcclusionImage)
m_filename(filename), : m_filename(filename)
m_baseName(QFileInfo(m_filename).baseName()) , m_baseName(QFileInfo(m_filename).baseName())
{ {
createFbxHeader(); createFbxHeader();
createFileId(); createFileId();
@ -2215,24 +2215,24 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
createGlobalSettings(); createGlobalSettings();
createDocuments(); createDocuments();
createReferences(); createReferences();
FBXNode connections("Connections"); FBXNode connections("Connections");
size_t deformerCount = 0; size_t deformerCount = 0;
FBXNode geometry("Geometry"); FBXNode geometry("Geometry");
int64_t geometryId = m_next64Id++; int64_t geometryId = m_next64Id++;
geometry.addProperty(geometryId); geometry.addProperty(geometryId);
geometry.addProperty(std::vector<uint8_t>({'u','n','a','m','e','d','m','e','s','h',0,1,'G','e','o','m','e','t','r','y'}), 'S'); geometry.addProperty(std::vector<uint8_t>({ 'u', 'n', 'a', 'm', 'e', 'd', 'm', 'e', 's', 'h', 0, 1, 'G', 'e', 'o', 'm', 'e', 't', 'r', 'y' }), 'S');
geometry.addProperty("Mesh"); geometry.addProperty("Mesh");
std::vector<double> positions; std::vector<double> positions;
for (const auto &vertex: object.vertices) { for (const auto& vertex : object.vertices) {
positions.push_back((double)vertex.x()); positions.push_back((double)vertex.x());
positions.push_back((double)vertex.y()); positions.push_back((double)vertex.y());
positions.push_back((double)vertex.z()); positions.push_back((double)vertex.z());
} }
std::vector<int32_t> indices; std::vector<int32_t> indices;
for (const auto &triangle: object.triangles) { for (const auto& triangle : object.triangles) {
indices.push_back(triangle[0]); indices.push_back(triangle[0]);
indices.push_back(triangle[1]); indices.push_back(triangle[1]);
indices.push_back(triangle[2] ^ -1); indices.push_back(triangle[2] ^ -1);
@ -2248,7 +2248,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
std::vector<double> normals; std::vector<double> normals;
for (decltype(triangleVertexNormals->size()) i = 0; i < triangleVertexNormals->size(); ++i) { for (decltype(triangleVertexNormals->size()) i = 0; i < triangleVertexNormals->size(); ++i) {
for (size_t j = 0; j < 3; ++j) { for (size_t j = 0; j < 3; ++j) {
const auto &n = (*triangleVertexNormals)[i][j]; const auto& n = (*triangleVertexNormals)[i][j];
normals.push_back((double)n.x()); normals.push_back((double)n.x());
normals.push_back((double)n.y()); normals.push_back((double)n.y());
normals.push_back((double)n.z()); normals.push_back((double)n.z());
@ -2269,7 +2269,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
//std::vector<int32_t> uvIndices; //std::vector<int32_t> uvIndices;
for (decltype(triangleVertexUvs->size()) i = 0; i < triangleVertexUvs->size(); ++i) { for (decltype(triangleVertexUvs->size()) i = 0; i < triangleVertexUvs->size(); ++i) {
for (size_t j = 0; j < 3; ++j) { for (size_t j = 0; j < 3; ++j) {
const auto &uv = (*triangleVertexUvs)[i][j]; const auto& uv = (*triangleVertexUvs)[i][j];
uvs.push_back((double)uv.x()); uvs.push_back((double)uv.x());
uvs.push_back((double)1.0 - uv.y()); uvs.push_back((double)1.0 - uv.y());
//uvIndices.push_back(uvIndices.size()); //uvIndices.push_back(uvIndices.size());
@ -2285,7 +2285,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
layerElementMaterial.addPropertyNode("Name", ""); layerElementMaterial.addPropertyNode("Name", "");
layerElementMaterial.addPropertyNode("MappingInformationType", "AllSame"); layerElementMaterial.addPropertyNode("MappingInformationType", "AllSame");
layerElementMaterial.addPropertyNode("ReferenceInformationType", "IndexToDirect"); layerElementMaterial.addPropertyNode("ReferenceInformationType", "IndexToDirect");
std::vector<int32_t> materials = {(int32_t)0}; std::vector<int32_t> materials = { (int32_t)0 };
layerElementMaterial.addPropertyNode("Materials", materials); layerElementMaterial.addPropertyNode("Materials", materials);
layerElementMaterial.addChild(FBXNode()); layerElementMaterial.addChild(FBXNode());
FBXNode layer("Layer"); FBXNode layer("Layer");
@ -2323,11 +2323,11 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
geometry.addChild(layerElementUv); geometry.addChild(layerElementUv);
geometry.addChild(layer); geometry.addChild(layer);
geometry.addChild(FBXNode()); geometry.addChild(FBXNode());
int64_t modelId = m_next64Id++; int64_t modelId = m_next64Id++;
FBXNode model("Model"); FBXNode model("Model");
model.addProperty(modelId); model.addProperty(modelId);
model.addProperty(std::vector<uint8_t>({'u','n','a','m','e','d',0,1,'M','o','d','e','l'}), 'S'); model.addProperty(std::vector<uint8_t>({ 'u', 'n', 'a', 'm', 'e', 'd', 0, 1, 'M', 'o', 'd', 'e', 'l' }), 'S');
model.addProperty("Mesh"); model.addProperty("Mesh");
model.addPropertyNode("Version", (int32_t)232); model.addPropertyNode("Version", (int32_t)232);
{ {
@ -2390,7 +2390,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
model.addPropertyNode("Shading", (bool)true); model.addPropertyNode("Shading", (bool)true);
model.addPropertyNode("Culling", "CullingOff"); model.addPropertyNode("Culling", "CullingOff");
model.addChild(FBXNode()); model.addChild(FBXNode());
FBXNode pose("Pose"); FBXNode pose("Pose");
int64_t poseId = 0; int64_t poseId = 0;
std::vector<FBXNode> deformers; std::vector<FBXNode> deformers;
@ -2401,12 +2401,11 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
std::vector<int64_t> nodeAttributeIds; std::vector<int64_t> nodeAttributeIds;
int64_t skinId = 0; int64_t skinId = 0;
int64_t armatureId = 0; int64_t armatureId = 0;
if (deformerCount > 0) if (deformerCount > 0) {
{
poseId = m_next64Id++; poseId = m_next64Id++;
pose.addProperty(poseId); pose.addProperty(poseId);
pose.addProperty(std::vector<uint8_t>({'u','n','a','m','e','d',0,1,'P','o','s','e'}), 'S'); pose.addProperty(std::vector<uint8_t>({ 'u', 'n', 'a', 'm', 'e', 'd', 0, 1, 'P', 'o', 's', 'e' }), 'S');
pose.addProperty("BindPose"); pose.addProperty("BindPose");
pose.addPropertyNode("Type", "BindPose"); pose.addPropertyNode("Type", "BindPose");
pose.addPropertyNode("Version", (int32_t)100); pose.addPropertyNode("Version", (int32_t)100);
@ -2427,17 +2426,17 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
} }
pose.addChild(FBXNode()); pose.addChild(FBXNode());
} }
size_t textureCount = 0; size_t textureCount = 0;
size_t videoCount = 0; size_t videoCount = 0;
std::vector<FBXNode> videos; std::vector<FBXNode> videos;
std::vector<FBXNode> textures; std::vector<FBXNode> textures;
FBXNode material("Material"); FBXNode material("Material");
int64_t materialId = m_next64Id++; int64_t materialId = m_next64Id++;
material.addProperty(materialId); material.addProperty(materialId);
material.addProperty(std::vector<uint8_t>({'M','a','t','e','r','i','a','l',0,1,'S','t','i','n','g','r','a','y','P','B','S'}), 'S'); material.addProperty(std::vector<uint8_t>({ 'M', 'a', 't', 'e', 'r', 'i', 'a', 'l', 0, 1, 'S', 't', 'i', 'n', 'g', 'r', 'a', 'y', 'P', 'B', 'S' }), 'S');
material.addProperty(""); material.addProperty("");
material.addPropertyNode("Version", (int32_t)102); material.addPropertyNode("Version", (int32_t)102);
material.addPropertyNode("ShadingModel", "unknown"); material.addPropertyNode("ShadingModel", "unknown");
@ -2696,7 +2695,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
material.addChild(properties); material.addChild(properties);
} }
material.addChild(FBXNode()); material.addChild(FBXNode());
/* /*
FBXNode material("Material"); FBXNode material("Material");
int64_t materialId = m_next64Id++; int64_t materialId = m_next64Id++;
@ -2833,11 +2832,11 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
} }
material.addChild(FBXNode()); material.addChild(FBXNode());
*/ */
FBXNode implementation("Implementation"); FBXNode implementation("Implementation");
int64_t implementationId = m_next64Id++; int64_t implementationId = m_next64Id++;
implementation.addProperty(implementationId); implementation.addProperty(implementationId);
implementation.addProperty(std::vector<uint8_t>({'I','m','p','l','e','m','e','n','t','a','t','i','o','n',0,1,'S','t','i','n','g','r','a','y','P','B','S','_','I','m','p','l','e','m','e','n','t','a','t','i','o','n'}), 'S'); implementation.addProperty(std::vector<uint8_t>({ 'I', 'm', 'p', 'l', 'e', 'm', 'e', 'n', 't', 'a', 't', 'i', 'o', 'n', 0, 1, 'S', 't', 'i', 'n', 'g', 'r', 'a', 'y', 'P', 'B', 'S', '_', 'I', 'm', 'p', 'l', 'e', 'm', 'e', 'n', 't', 'a', 't', 'i', 'o', 'n' }), 'S');
implementation.addProperty(""); implementation.addProperty("");
implementation.addPropertyNode("Version", (int32_t)100); implementation.addPropertyNode("Version", (int32_t)100);
{ {
@ -2896,11 +2895,11 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
implementation.addChild(properties); implementation.addChild(properties);
} }
implementation.addChild(FBXNode()); implementation.addChild(FBXNode());
FBXNode bindingTable("BindingTable"); FBXNode bindingTable("BindingTable");
int64_t bindingTableId = m_next64Id++; int64_t bindingTableId = m_next64Id++;
bindingTable.addProperty(bindingTableId); bindingTable.addProperty(bindingTableId);
bindingTable.addProperty(std::vector<uint8_t>({'B','i','n','d','i','n','g','T','a','b','l','e',0,1,'S','t','i','n','g','r','a','y','P','B','S','_','B','i','n','d','i','n','g','T','a','b','l','e'}), 'S'); bindingTable.addProperty(std::vector<uint8_t>({ 'B', 'i', 'n', 'd', 'i', 'n', 'g', 'T', 'a', 'b', 'l', 'e', 0, 1, 'S', 't', 'i', 'n', 'g', 'r', 'a', 'y', 'P', 'B', 'S', '_', 'B', 'i', 'n', 'd', 'i', 'n', 'g', 'T', 'a', 'b', 'l', 'e' }), 'S');
bindingTable.addProperty(""); bindingTable.addProperty("");
bindingTable.addPropertyNode("Version", (int32_t)100); bindingTable.addPropertyNode("Version", (int32_t)100);
{ {
@ -3103,8 +3102,8 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
bindingTable.addChild(entry); bindingTable.addChild(entry);
} }
bindingTable.addChild(FBXNode()); bindingTable.addChild(FBXNode());
auto addTexture = [&](const QImage *image, const std::vector<uint8_t> &clipName, const std::vector<uint8_t> &textureName, const QString &filename, const QString &propertyName){ auto addTexture = [&](const QImage* image, const std::vector<uint8_t>& clipName, const std::vector<uint8_t>& textureName, const QString& filename, const QString& propertyName) {
FBXNode video("Video"); FBXNode video("Video");
int64_t videoId = m_next64Id++; int64_t videoId = m_next64Id++;
video.addProperty(videoId); video.addProperty(videoId);
@ -3136,7 +3135,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
video.addChild(FBXNode()); video.addChild(FBXNode());
videos.push_back(video); videos.push_back(video);
videoCount++; videoCount++;
FBXNode texture("Texture"); FBXNode texture("Texture");
int64_t textureId = m_next64Id++; int64_t textureId = m_next64Id++;
texture.addProperty(textureId); texture.addProperty(textureId);
@ -3195,7 +3194,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
texture.addChild(FBXNode()); texture.addChild(FBXNode());
textures.push_back(texture); textures.push_back(texture);
textureCount++; textureCount++;
{ {
FBXNode p("C"); FBXNode p("C");
p.addProperty("OO"); p.addProperty("OO");
@ -3214,46 +3213,46 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
}; };
if (nullptr != textureImage) { if (nullptr != textureImage) {
addTexture(textureImage, addTexture(textureImage,
std::vector<uint8_t>({'V','i','d','e','o',0,1,'B','a','s','e','C','o','l','o','r'}), std::vector<uint8_t>({ 'V', 'i', 'd', 'e', 'o', 0, 1, 'B', 'a', 's', 'e', 'C', 'o', 'l', 'o', 'r' }),
std::vector<uint8_t>({'T','e','x','t','u','r','e',0,1,'B','a','s','e','C','o','l','o','r'}), std::vector<uint8_t>({ 'T', 'e', 'x', 't', 'u', 'r', 'e', 0, 1, 'B', 'a', 's', 'e', 'C', 'o', 'l', 'o', 'r' }),
m_baseName + "_color.png", m_baseName + "_color.png",
"Maya|TEX_color_map"); "Maya|TEX_color_map");
} }
if (nullptr != normalImage) { if (nullptr != normalImage) {
addTexture(normalImage, addTexture(normalImage,
std::vector<uint8_t>({'V','i','d','e','o',0,1,'N','o','r','m','a','l'}), std::vector<uint8_t>({ 'V', 'i', 'd', 'e', 'o', 0, 1, 'N', 'o', 'r', 'm', 'a', 'l' }),
std::vector<uint8_t>({'T','e','x','t','u','r','e',0,1,'N','o','r','m','a','l'}), std::vector<uint8_t>({ 'T', 'e', 'x', 't', 'u', 'r', 'e', 0, 1, 'N', 'o', 'r', 'm', 'a', 'l' }),
m_baseName + "_normal.png", m_baseName + "_normal.png",
"Maya|TEX_normal_map"); "Maya|TEX_normal_map");
} }
if (nullptr != metalnessImage) { if (nullptr != metalnessImage) {
addTexture(metalnessImage, addTexture(metalnessImage,
std::vector<uint8_t>({'V','i','d','e','o',0,1,'M','e','t','a','l','l','i','c'}), std::vector<uint8_t>({ 'V', 'i', 'd', 'e', 'o', 0, 1, 'M', 'e', 't', 'a', 'l', 'l', 'i', 'c' }),
std::vector<uint8_t>({'T','e','x','t','u','r','e',0,1,'M','e','t','a','l','l','i','c'}), std::vector<uint8_t>({ 'T', 'e', 'x', 't', 'u', 'r', 'e', 0, 1, 'M', 'e', 't', 'a', 'l', 'l', 'i', 'c' }),
m_baseName + "_metallic.png", m_baseName + "_metallic.png",
"Maya|TEX_metallic_map"); "Maya|TEX_metallic_map");
} }
if (nullptr != roughnessImage) { if (nullptr != roughnessImage) {
addTexture(roughnessImage, addTexture(roughnessImage,
std::vector<uint8_t>({'V','i','d','e','o',0,1,'R','o','u','g','h','n','e','s','s'}), std::vector<uint8_t>({ 'V', 'i', 'd', 'e', 'o', 0, 1, 'R', 'o', 'u', 'g', 'h', 'n', 'e', 's', 's' }),
std::vector<uint8_t>({'T','e','x','t','u','r','e',0,1,'R','o','u','g','h','n','e','s','s'}), std::vector<uint8_t>({ 'T', 'e', 'x', 't', 'u', 'r', 'e', 0, 1, 'R', 'o', 'u', 'g', 'h', 'n', 'e', 's', 's' }),
m_baseName + "_roughness.png", m_baseName + "_roughness.png",
"Maya|TEX_roughness_map"); "Maya|TEX_roughness_map");
} }
if (nullptr != ambientOcclusionImage) { if (nullptr != ambientOcclusionImage) {
addTexture(ambientOcclusionImage, addTexture(ambientOcclusionImage,
std::vector<uint8_t>({'V','i','d','e','o',0,1,'A','o'}), std::vector<uint8_t>({ 'V', 'i', 'd', 'e', 'o', 0, 1, 'A', 'o' }),
std::vector<uint8_t>({'T','e','x','t','u','r','e',0,1,'A','o'}), std::vector<uint8_t>({ 'T', 'e', 'x', 't', 'u', 'r', 'e', 0, 1, 'A', 'o' }),
m_baseName + "_ao.png", m_baseName + "_ao.png",
"Maya|TEX_ao_map"); "Maya|TEX_ao_map");
} }
bool hasAnimation = false; bool hasAnimation = false;
size_t animationStackCount = 0; size_t animationStackCount = 0;
size_t animationLayerCount = 0; size_t animationLayerCount = 0;
size_t animationCurveNodeCount = 0; size_t animationCurveNodeCount = 0;
size_t animationCurveCount = 0; size_t animationCurveCount = 0;
std::vector<FBXNode> animationStacks; std::vector<FBXNode> animationStacks;
std::vector<FBXNode> animationLayers; std::vector<FBXNode> animationLayers;
std::vector<FBXNode> animationCurveNodes; std::vector<FBXNode> animationCurveNodes;
@ -3263,11 +3262,11 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
textureCount, videoCount, textureCount, videoCount,
hasAnimation, hasAnimation,
animationStackCount, animationLayerCount, animationCurveNodeCount, animationCurveCount); animationStackCount, animationLayerCount, animationCurveNodeCount, animationCurveCount);
FBXNode objects("Objects"); FBXNode objects("Objects");
objects.addChild(geometry); objects.addChild(geometry);
objects.addChild(model); objects.addChild(model);
for (const auto &limbNode: limbNodes) { for (const auto& limbNode : limbNodes) {
objects.addChild(limbNode); objects.addChild(limbNode);
} }
if (deformerCount > 0) if (deformerCount > 0)
@ -3276,38 +3275,38 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
objects.addChild(implementation); objects.addChild(implementation);
objects.addChild(bindingTable); objects.addChild(bindingTable);
if (textureCount > 0) { if (textureCount > 0) {
for (const auto &texture: textures) { for (const auto& texture : textures) {
objects.addChild(texture); objects.addChild(texture);
} }
} }
if (videoCount > 0) { if (videoCount > 0) {
for (const auto &video: videos) { for (const auto& video : videos) {
objects.addChild(video); objects.addChild(video);
} }
} }
for (const auto &deformer: deformers) { for (const auto& deformer : deformers) {
objects.addChild(deformer); objects.addChild(deformer);
} }
for (const auto &nodeAttribute: nodeAttributes) { for (const auto& nodeAttribute : nodeAttributes) {
objects.addChild(nodeAttribute); objects.addChild(nodeAttribute);
} }
if (hasAnimation) { if (hasAnimation) {
for (const auto &animationStack: animationStacks) { for (const auto& animationStack : animationStacks) {
objects.addChild(animationStack); objects.addChild(animationStack);
} }
for (const auto &animationLayer: animationLayers) { for (const auto& animationLayer : animationLayers) {
objects.addChild(animationLayer); objects.addChild(animationLayer);
} }
for (const auto &animationCurveNode: animationCurveNodes) { for (const auto& animationCurveNode : animationCurveNodes) {
objects.addChild(animationCurveNode); objects.addChild(animationCurveNode);
} }
for (const auto &animationCurve: animationCurves) { for (const auto& animationCurve : animationCurves) {
objects.addChild(animationCurve); objects.addChild(animationCurve);
} }
} }
objects.addChild(FBXNode()); objects.addChild(FBXNode());
m_fbxDocument.nodes.push_back(objects); m_fbxDocument.nodes.push_back(objects);
{ {
FBXNode p("C"); FBXNode p("C");
p.addProperty("OO"); p.addProperty("OO");
@ -3315,8 +3314,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
p.addProperty((int64_t)0); p.addProperty((int64_t)0);
connections.addChild(p); connections.addChild(p);
} }
if (armatureId > 0) if (armatureId > 0) {
{
FBXNode p("C"); FBXNode p("C");
p.addProperty("OO"); p.addProperty("OO");
p.addProperty(armatureId); p.addProperty(armatureId);
@ -3330,8 +3328,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
p.addProperty(modelId); p.addProperty(modelId);
connections.addChild(p); connections.addChild(p);
} }
if (skinId > 0) if (skinId > 0) {
{
FBXNode p("C"); FBXNode p("C");
p.addProperty("OO"); p.addProperty("OO");
p.addProperty(skinId); p.addProperty(skinId);
@ -3375,7 +3372,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
} }
connections.addChild(FBXNode()); connections.addChild(FBXNode());
m_fbxDocument.nodes.push_back(connections); m_fbxDocument.nodes.push_back(connections);
createTakes(); createTakes();
} }
@ -3394,11 +3391,11 @@ bool FbxFileWriter::save()
return true; return true;
} }
std::vector<double> FbxFileWriter::matrixToVector(const QMatrix4x4 &matrix) std::vector<double> FbxFileWriter::matrixToVector(const QMatrix4x4& matrix)
{ {
std::vector<double> vec; std::vector<double> vec;
for (size_t col = 0; col < 4; ++col) { for (size_t col = 0; col < 4; ++col) {
const auto &line = matrix.column(col); const auto& line = matrix.column(col);
vec.push_back(line.x()); vec.push_back(line.x());
vec.push_back(line.y()); vec.push_back(line.y());
vec.push_back(line.z()); vec.push_back(line.z());

View File

@ -1,25 +1,24 @@
#ifndef DUST3D_APPLICATION_FBX_FILE_H_ #ifndef DUST3D_APPLICATION_FBX_FILE_H_
#define DUST3D_APPLICATION_FBX_FILE_H_ #define DUST3D_APPLICATION_FBX_FILE_H_
#include <map> #include "fbxdocument.h"
#include <QString> #include <QImage>
#include <QMatrix4x4> #include <QMatrix4x4>
#include <QQuaternion> #include <QQuaternion>
#include <QImage> #include <QString>
#include <dust3d/base/object.h> #include <dust3d/base/object.h>
#include "fbxdocument.h" #include <map>
class FbxFileWriter : public QObject class FbxFileWriter : public QObject {
{
Q_OBJECT Q_OBJECT
public: public:
FbxFileWriter(dust3d::Object &object, FbxFileWriter(dust3d::Object& object,
const QString &filename, const QString& filename,
QImage *textureImage=nullptr, QImage* textureImage = nullptr,
QImage *normalImage=nullptr, QImage* normalImage = nullptr,
QImage *metalnessImage=nullptr, QImage* metalnessImage = nullptr,
QImage *roughnessImage=nullptr, QImage* roughnessImage = nullptr,
QImage *ambientOcclusionImage=nullptr); QImage* ambientOcclusionImage = nullptr);
bool save(); bool save();
private: private:
@ -31,17 +30,17 @@ private:
void createDocuments(); void createDocuments();
void createReferences(); void createReferences();
void createDefinitions(size_t deformerCount, void createDefinitions(size_t deformerCount,
size_t textureCount=0, size_t textureCount = 0,
size_t videoCount=0, size_t videoCount = 0,
bool hasAnimtion=false, bool hasAnimtion = false,
size_t animationStackCount=0, size_t animationStackCount = 0,
size_t animationLayerCount=0, size_t animationLayerCount = 0,
size_t animationCurveNodeCount=0, size_t animationCurveNodeCount = 0,
size_t animationCurveCount=0); size_t animationCurveCount = 0);
void createTakes(); void createTakes();
std::vector<double> matrixToVector(const QMatrix4x4 &matrix); std::vector<double> matrixToVector(const QMatrix4x4& matrix);
int64_t secondsToKtime(double seconds); int64_t secondsToKtime(double seconds);
int64_t m_next64Id = 612150000; int64_t m_next64Id = 612150000;
QString m_filename; QString m_filename;
QString m_baseName; QString m_baseName;
@ -51,4 +50,3 @@ private:
}; };
#endif #endif

View File

@ -1,11 +1,11 @@
#include <QtWidgets> #include "float_number_widget.h"
#include "theme.h"
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QVBoxLayout> #include <QVBoxLayout>
#include "theme.h" #include <QtWidgets>
#include "float_number_widget.h"
FloatNumberWidget::FloatNumberWidget(QWidget *parent, bool singleLine) : FloatNumberWidget::FloatNumberWidget(QWidget* parent, bool singleLine)
QWidget(parent) : QWidget(parent)
{ {
m_slider = new QSlider(Qt::Horizontal, this); m_slider = new QSlider(Qt::Horizontal, this);
m_slider->setRange(0, 100); m_slider->setRange(0, 100);
@ -19,8 +19,8 @@ FloatNumberWidget::FloatNumberWidget(QWidget *parent, bool singleLine) :
updateValueLabel(fvalue); updateValueLabel(fvalue);
emit valueChanged(fvalue); emit valueChanged(fvalue);
}); });
QBoxLayout *layout = nullptr; QBoxLayout* layout = nullptr;
if (singleLine) { if (singleLine) {
layout = new QHBoxLayout(this); layout = new QHBoxLayout(this);
layout->setMargin(2); layout->setMargin(2);
@ -48,7 +48,7 @@ void FloatNumberWidget::updateValueLabel(float value)
m_label->setText(m_itemName + ": " + valueString); m_label->setText(m_itemName + ": " + valueString);
} }
void FloatNumberWidget::setItemName(const QString &name) void FloatNumberWidget::setItemName(const QString& name)
{ {
m_itemName = name; m_itemName = name;
updateValueLabel(value()); updateValueLabel(value());

View File

@ -6,14 +6,13 @@
QT_FORWARD_DECLARE_CLASS(QLabel) QT_FORWARD_DECLARE_CLASS(QLabel)
QT_FORWARD_DECLARE_CLASS(QSlider) QT_FORWARD_DECLARE_CLASS(QSlider)
class FloatNumberWidget : public QWidget class FloatNumberWidget : public QWidget {
{
Q_OBJECT Q_OBJECT
public: public:
explicit FloatNumberWidget(QWidget *parent=nullptr, bool singleLine=true); explicit FloatNumberWidget(QWidget* parent = nullptr, bool singleLine = true);
void setRange(float min, float max); void setRange(float min, float max);
float value() const; float value() const;
void setItemName(const QString &name); void setItemName(const QString& name);
void setSliderFixedWidth(float width); void setSliderFixedWidth(float width);
public slots: public slots:
@ -23,13 +22,13 @@ public slots:
signals: signals:
void valueChanged(float value); void valueChanged(float value);
private: private:
void updateValueLabel(float value); void updateValueLabel(float value);
private: private:
QLabel *m_label = nullptr; QLabel* m_label = nullptr;
QSlider *m_slider = nullptr; QSlider* m_slider = nullptr;
QString m_itemName; QString m_itemName;
}; };

View File

@ -52,26 +52,29 @@
#include "flow_layout.h" #include "flow_layout.h"
FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing) FlowLayout::FlowLayout(QWidget* parent, int margin, int hSpacing, int vSpacing)
: QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing) : QLayout(parent)
, m_hSpace(hSpacing)
, m_vSpace(vSpacing)
{ {
setContentsMargins(margin, margin, margin, margin); setContentsMargins(margin, margin, margin, margin);
} }
FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing) FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing)
: m_hSpace(hSpacing), m_vSpace(vSpacing) : m_hSpace(hSpacing)
, m_vSpace(vSpacing)
{ {
setContentsMargins(margin, margin, margin, margin); setContentsMargins(margin, margin, margin, margin);
} }
FlowLayout::~FlowLayout() FlowLayout::~FlowLayout()
{ {
QLayoutItem *item; QLayoutItem* item;
while ((item = takeAt(0))) while ((item = takeAt(0)))
delete item; delete item;
} }
void FlowLayout::addItem(QLayoutItem *item) void FlowLayout::addItem(QLayoutItem* item)
{ {
itemList.append(item); itemList.append(item);
} }
@ -99,12 +102,12 @@ int FlowLayout::count() const
return itemList.size(); return itemList.size();
} }
QLayoutItem *FlowLayout::itemAt(int index) const QLayoutItem* FlowLayout::itemAt(int index) const
{ {
return itemList.value(index); return itemList.value(index);
} }
QLayoutItem *FlowLayout::takeAt(int index) QLayoutItem* FlowLayout::takeAt(int index)
{ {
if (index >= 0 && index < itemList.size()) if (index >= 0 && index < itemList.size())
return itemList.takeAt(index); return itemList.takeAt(index);
@ -128,7 +131,7 @@ int FlowLayout::heightForWidth(int width) const
return height; return height;
} }
void FlowLayout::setGeometry(const QRect &rect) void FlowLayout::setGeometry(const QRect& rect)
{ {
QLayout::setGeometry(rect); QLayout::setGeometry(rect);
doLayout(rect, false); doLayout(rect, false);
@ -142,15 +145,15 @@ QSize FlowLayout::sizeHint() const
QSize FlowLayout::minimumSize() const QSize FlowLayout::minimumSize() const
{ {
QSize size; QSize size;
QLayoutItem *item; QLayoutItem* item;
foreach (item, itemList) foreach (item, itemList)
size = size.expandedTo(item->minimumSize()); size = size.expandedTo(item->minimumSize());
size += QSize(2*margin(), 2*margin()); size += QSize(2 * margin(), 2 * margin());
return size; return size;
} }
int FlowLayout::doLayout(const QRect &rect, bool testOnly) const int FlowLayout::doLayout(const QRect& rect, bool testOnly) const
{ {
int left, top, right, bottom; int left, top, right, bottom;
getContentsMargins(&left, &top, &right, &bottom); getContentsMargins(&left, &top, &right, &bottom);
@ -159,9 +162,9 @@ int FlowLayout::doLayout(const QRect &rect, bool testOnly) const
int y = effectiveRect.y(); int y = effectiveRect.y();
int lineHeight = 0; int lineHeight = 0;
QLayoutItem *item; QLayoutItem* item;
foreach (item, itemList) { foreach (item, itemList) {
QWidget *wid = item->widget(); QWidget* wid = item->widget();
int spaceX = horizontalSpacing(); int spaceX = horizontalSpacing();
if (spaceX == -1) if (spaceX == -1)
spaceX = wid->style()->layoutSpacing( spaceX = wid->style()->layoutSpacing(
@ -189,13 +192,13 @@ int FlowLayout::doLayout(const QRect &rect, bool testOnly) const
int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const
{ {
QObject *parent = this->parent(); QObject* parent = this->parent();
if (!parent) { if (!parent) {
return -1; return -1;
} else if (parent->isWidgetType()) { } else if (parent->isWidgetType()) {
QWidget *pw = static_cast<QWidget *>(parent); QWidget* pw = static_cast<QWidget*>(parent);
return pw->style()->pixelMetric(pm, 0, pw); return pw->style()->pixelMetric(pm, 0, pw);
} else { } else {
return static_cast<QLayout *>(parent)->spacing(); return static_cast<QLayout*>(parent)->spacing();
} }
} }

View File

@ -55,31 +55,30 @@
#include <QRect> #include <QRect>
#include <QStyle> #include <QStyle>
class FlowLayout : public QLayout class FlowLayout : public QLayout {
{
public: public:
explicit FlowLayout(QWidget *parent, int margin=-1, int hSpacing=-1, int vSpacing=-1); explicit FlowLayout(QWidget* parent, int margin = -1, int hSpacing = -1, int vSpacing = -1);
explicit FlowLayout(int margin=-1, int hSpacing=-1, int vSpacing=-1); explicit FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1);
~FlowLayout(); ~FlowLayout();
void addItem(QLayoutItem *item) override; void addItem(QLayoutItem* item) override;
int horizontalSpacing() const; int horizontalSpacing() const;
int verticalSpacing() const; int verticalSpacing() const;
Qt::Orientations expandingDirections() const override; Qt::Orientations expandingDirections() const override;
bool hasHeightForWidth() const override; bool hasHeightForWidth() const override;
int heightForWidth(int) const override; int heightForWidth(int) const override;
int count() const override; int count() const override;
QLayoutItem *itemAt(int index) const override; QLayoutItem* itemAt(int index) const override;
QSize minimumSize() const override; QSize minimumSize() const override;
void setGeometry(const QRect &rect) override; void setGeometry(const QRect& rect) override;
QSize sizeHint() const override; QSize sizeHint() const override;
QLayoutItem *takeAt(int index) override; QLayoutItem* takeAt(int index) override;
private: private:
int doLayout(const QRect &rect, bool testOnly) const; int doLayout(const QRect& rect, bool testOnly) const;
int smartSpacing(QStyle::PixelMetric pm) const; int smartSpacing(QStyle::PixelMetric pm) const;
QList<QLayoutItem *> itemList; QList<QLayoutItem*> itemList;
int m_hSpace; int m_hSpace;
int m_vSpace; int m_vSpace;
}; };

View File

@ -1,29 +1,29 @@
#include <QFile> #include "glb_file.h"
#include <QQuaternion> #include "model_mesh.h"
#include "version.h"
#include <QByteArray> #include <QByteArray>
#include <QDataStream> #include <QDataStream>
#include <QFileInfo>
#include <QDir> #include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QQuaternion>
#include <QtCore/qbuffer.h> #include <QtCore/qbuffer.h>
#include "glb_file.h"
#include "version.h"
#include "model_mesh.h"
bool GlbFileWriter::m_enableComment = false; bool GlbFileWriter::m_enableComment = false;
GlbFileWriter::GlbFileWriter(dust3d::Object &object, GlbFileWriter::GlbFileWriter(dust3d::Object& object,
const QString &filename, const QString& filename,
QImage *textureImage, QImage* textureImage,
QImage *normalImage, QImage* normalImage,
QImage *ormImage) : QImage* ormImage)
m_filename(filename) : m_filename(filename)
{ {
const std::vector<std::vector<dust3d::Vector3>> *triangleVertexNormals = object.triangleVertexNormals(); const std::vector<std::vector<dust3d::Vector3>>* triangleVertexNormals = object.triangleVertexNormals();
if (m_outputNormal) { if (m_outputNormal) {
m_outputNormal = nullptr != triangleVertexNormals; m_outputNormal = nullptr != triangleVertexNormals;
} }
const std::vector<std::vector<dust3d::Vector2>> *triangleVertexUvs = object.triangleVertexUvs(); const std::vector<std::vector<dust3d::Vector2>>* triangleVertexUvs = object.triangleVertexUvs();
if (m_outputUv) { if (m_outputUv) {
m_outputUv = nullptr != triangleVertexUvs; m_outputUv = nullptr != triangleVertexUvs;
} }
@ -31,35 +31,35 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object,
QDataStream binStream(&m_binByteArray, QIODevice::WriteOnly); QDataStream binStream(&m_binByteArray, QIODevice::WriteOnly);
binStream.setFloatingPointPrecision(QDataStream::SinglePrecision); binStream.setFloatingPointPrecision(QDataStream::SinglePrecision);
binStream.setByteOrder(QDataStream::LittleEndian); binStream.setByteOrder(QDataStream::LittleEndian);
auto alignBin = [this, &binStream] { auto alignBin = [this, &binStream] {
while (0 != this->m_binByteArray.size() % 4) { while (0 != this->m_binByteArray.size() % 4) {
binStream << (quint8)0; binStream << (quint8)0;
} }
}; };
QDataStream jsonStream(&m_jsonByteArray, QIODevice::WriteOnly); QDataStream jsonStream(&m_jsonByteArray, QIODevice::WriteOnly);
jsonStream.setFloatingPointPrecision(QDataStream::SinglePrecision); jsonStream.setFloatingPointPrecision(QDataStream::SinglePrecision);
jsonStream.setByteOrder(QDataStream::LittleEndian); jsonStream.setByteOrder(QDataStream::LittleEndian);
auto alignJson = [this, &jsonStream] { auto alignJson = [this, &jsonStream] {
while (0 != this->m_jsonByteArray.size() % 4) { while (0 != this->m_jsonByteArray.size() % 4) {
jsonStream << (quint8)' '; jsonStream << (quint8)' ';
} }
}; };
int bufferViewIndex = 0; int bufferViewIndex = 0;
int bufferViewFromOffset; int bufferViewFromOffset;
m_json["asset"]["version"] = "2.0"; m_json["asset"]["version"] = "2.0";
m_json["asset"]["generator"] = APP_NAME " " APP_HUMAN_VER; m_json["asset"]["generator"] = APP_NAME " " APP_HUMAN_VER;
m_json["scenes"][0]["nodes"] = {0}; m_json["scenes"][0]["nodes"] = { 0 };
m_json["nodes"][0]["mesh"] = 0; m_json["nodes"][0]["mesh"] = 0;
std::vector<dust3d::Vector3> triangleVertexPositions; std::vector<dust3d::Vector3> triangleVertexPositions;
std::vector<size_t> triangleVertexOldIndices; std::vector<size_t> triangleVertexOldIndices;
for (const auto &triangleIndices: object.triangles) { for (const auto& triangleIndices : object.triangles) {
for (size_t j = 0; j < 3; ++j) { for (size_t j = 0; j < 3; ++j) {
triangleVertexOldIndices.push_back(triangleIndices[j]); triangleVertexOldIndices.push_back(triangleIndices[j]);
triangleVertexPositions.push_back(object.vertices[triangleIndices[j]]); triangleVertexPositions.push_back(object.vertices[triangleIndices[j]]);
@ -68,7 +68,7 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object,
int primitiveIndex = 0; int primitiveIndex = 0;
if (!triangleVertexPositions.empty()) { if (!triangleVertexPositions.empty()) {
m_json["meshes"][0]["primitives"][primitiveIndex]["indices"] = bufferViewIndex; m_json["meshes"][0]["primitives"][primitiveIndex]["indices"] = bufferViewIndex;
m_json["meshes"][0]["primitives"][primitiveIndex]["material"] = primitiveIndex; m_json["meshes"][0]["primitives"][primitiveIndex]["material"] = primitiveIndex;
int attributeIndex = 0; int attributeIndex = 0;
@ -93,7 +93,7 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object,
m_json["materials"][primitiveIndex]["pbrMetallicRoughness"]["roughnessFactor"] = 1.0; m_json["materials"][primitiveIndex]["pbrMetallicRoughness"]["roughnessFactor"] = 1.0;
textureIndex++; textureIndex++;
} }
primitiveIndex++; primitiveIndex++;
bufferViewFromOffset = (int)m_binByteArray.size(); bufferViewFromOffset = (int)m_binByteArray.size();
@ -114,7 +114,7 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object,
m_json["accessors"][bufferViewIndex]["count"] = triangleVertexPositions.size(); m_json["accessors"][bufferViewIndex]["count"] = triangleVertexPositions.size();
m_json["accessors"][bufferViewIndex]["type"] = "SCALAR"; m_json["accessors"][bufferViewIndex]["type"] = "SCALAR";
bufferViewIndex++; bufferViewIndex++;
bufferViewFromOffset = (int)m_binByteArray.size(); bufferViewFromOffset = (int)m_binByteArray.size();
m_json["bufferViews"][bufferViewIndex]["buffer"] = 0; m_json["bufferViews"][bufferViewIndex]["buffer"] = 0;
m_json["bufferViews"][bufferViewIndex]["byteOffset"] = bufferViewFromOffset; m_json["bufferViews"][bufferViewIndex]["byteOffset"] = bufferViewFromOffset;
@ -124,7 +124,7 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object,
float maxY = -100; float maxY = -100;
float minZ = 100; float minZ = 100;
float maxZ = -100; float maxZ = -100;
for (const auto &position: triangleVertexPositions) { for (const auto& position : triangleVertexPositions) {
if (position.x() < minX) if (position.x() < minX)
minX = position.x(); minX = position.x();
if (position.x() > maxX) if (position.x() > maxX)
@ -140,7 +140,7 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object,
binStream << (float)position.x() << (float)position.y() << (float)position.z(); binStream << (float)position.x() << (float)position.y() << (float)position.z();
} }
Q_ASSERT((int)triangleVertexPositions.size() * 3 * sizeof(float) == m_binByteArray.size() - bufferViewFromOffset); Q_ASSERT((int)triangleVertexPositions.size() * 3 * sizeof(float) == m_binByteArray.size() - bufferViewFromOffset);
m_json["bufferViews"][bufferViewIndex]["byteLength"] = triangleVertexPositions.size() * 3 * sizeof(float); m_json["bufferViews"][bufferViewIndex]["byteLength"] = triangleVertexPositions.size() * 3 * sizeof(float);
m_json["bufferViews"][bufferViewIndex]["target"] = 34962; m_json["bufferViews"][bufferViewIndex]["target"] = 34962;
alignBin(); alignBin();
if (m_enableComment) if (m_enableComment)
@ -148,26 +148,26 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object,
m_json["accessors"][bufferViewIndex]["bufferView"] = bufferViewIndex; m_json["accessors"][bufferViewIndex]["bufferView"] = bufferViewIndex;
m_json["accessors"][bufferViewIndex]["byteOffset"] = 0; m_json["accessors"][bufferViewIndex]["byteOffset"] = 0;
m_json["accessors"][bufferViewIndex]["componentType"] = 5126; m_json["accessors"][bufferViewIndex]["componentType"] = 5126;
m_json["accessors"][bufferViewIndex]["count"] = triangleVertexPositions.size(); m_json["accessors"][bufferViewIndex]["count"] = triangleVertexPositions.size();
m_json["accessors"][bufferViewIndex]["type"] = "VEC3"; m_json["accessors"][bufferViewIndex]["type"] = "VEC3";
m_json["accessors"][bufferViewIndex]["max"] = {maxX, maxY, maxZ}; m_json["accessors"][bufferViewIndex]["max"] = { maxX, maxY, maxZ };
m_json["accessors"][bufferViewIndex]["min"] = {minX, minY, minZ}; m_json["accessors"][bufferViewIndex]["min"] = { minX, minY, minZ };
bufferViewIndex++; bufferViewIndex++;
if (m_outputNormal) { if (m_outputNormal) {
bufferViewFromOffset = (int)m_binByteArray.size(); bufferViewFromOffset = (int)m_binByteArray.size();
m_json["bufferViews"][bufferViewIndex]["buffer"] = 0; m_json["bufferViews"][bufferViewIndex]["buffer"] = 0;
m_json["bufferViews"][bufferViewIndex]["byteOffset"] = bufferViewFromOffset; m_json["bufferViews"][bufferViewIndex]["byteOffset"] = bufferViewFromOffset;
QStringList normalList; QStringList normalList;
for (const auto &normals: (*triangleVertexNormals)) { for (const auto& normals : (*triangleVertexNormals)) {
for (const auto &it: normals) { for (const auto& it : normals) {
binStream << (float)it.x() << (float)it.y() << (float)it.z(); binStream << (float)it.x() << (float)it.y() << (float)it.z();
if (m_enableComment && m_outputNormal) if (m_enableComment && m_outputNormal)
normalList.append(QString("<%1,%2,%3>").arg(QString::number(it.x())).arg(QString::number(it.y())).arg(QString::number(it.z()))); normalList.append(QString("<%1,%2,%3>").arg(QString::number(it.x())).arg(QString::number(it.y())).arg(QString::number(it.z())));
} }
} }
Q_ASSERT((int)triangleVertexNormals->size() * 3 * 3 * sizeof(float) == m_binByteArray.size() - bufferViewFromOffset); Q_ASSERT((int)triangleVertexNormals->size() * 3 * 3 * sizeof(float) == m_binByteArray.size() - bufferViewFromOffset);
m_json["bufferViews"][bufferViewIndex]["byteLength"] = triangleVertexNormals->size() * 3 * 3 * sizeof(float); m_json["bufferViews"][bufferViewIndex]["byteLength"] = triangleVertexNormals->size() * 3 * 3 * sizeof(float);
m_json["bufferViews"][bufferViewIndex]["target"] = 34962; m_json["bufferViews"][bufferViewIndex]["target"] = 34962;
alignBin(); alignBin();
if (m_enableComment) if (m_enableComment)
@ -175,17 +175,17 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object,
m_json["accessors"][bufferViewIndex]["bufferView"] = bufferViewIndex; m_json["accessors"][bufferViewIndex]["bufferView"] = bufferViewIndex;
m_json["accessors"][bufferViewIndex]["byteOffset"] = 0; m_json["accessors"][bufferViewIndex]["byteOffset"] = 0;
m_json["accessors"][bufferViewIndex]["componentType"] = 5126; m_json["accessors"][bufferViewIndex]["componentType"] = 5126;
m_json["accessors"][bufferViewIndex]["count"] = triangleVertexNormals->size() * 3; m_json["accessors"][bufferViewIndex]["count"] = triangleVertexNormals->size() * 3;
m_json["accessors"][bufferViewIndex]["type"] = "VEC3"; m_json["accessors"][bufferViewIndex]["type"] = "VEC3";
bufferViewIndex++; bufferViewIndex++;
} }
if (m_outputUv) { if (m_outputUv) {
bufferViewFromOffset = (int)m_binByteArray.size(); bufferViewFromOffset = (int)m_binByteArray.size();
m_json["bufferViews"][bufferViewIndex]["buffer"] = 0; m_json["bufferViews"][bufferViewIndex]["buffer"] = 0;
m_json["bufferViews"][bufferViewIndex]["byteOffset"] = bufferViewFromOffset; m_json["bufferViews"][bufferViewIndex]["byteOffset"] = bufferViewFromOffset;
for (const auto &uvs: (*triangleVertexUvs)) { for (const auto& uvs : (*triangleVertexUvs)) {
for (const auto &it: uvs) for (const auto& it : uvs)
binStream << (float)it.x() << (float)it.y(); binStream << (float)it.x() << (float)it.y();
} }
m_json["bufferViews"][bufferViewIndex]["byteLength"] = m_binByteArray.size() - bufferViewFromOffset; m_json["bufferViews"][bufferViewIndex]["byteLength"] = m_binByteArray.size() - bufferViewFromOffset;
@ -195,7 +195,7 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object,
m_json["accessors"][bufferViewIndex]["bufferView"] = bufferViewIndex; m_json["accessors"][bufferViewIndex]["bufferView"] = bufferViewIndex;
m_json["accessors"][bufferViewIndex]["byteOffset"] = 0; m_json["accessors"][bufferViewIndex]["byteOffset"] = 0;
m_json["accessors"][bufferViewIndex]["componentType"] = 5126; m_json["accessors"][bufferViewIndex]["componentType"] = 5126;
m_json["accessors"][bufferViewIndex]["count"] = triangleVertexUvs->size() * 3; m_json["accessors"][bufferViewIndex]["count"] = triangleVertexUvs->size() * 3;
m_json["accessors"][bufferViewIndex]["type"] = "VEC2"; m_json["accessors"][bufferViewIndex]["type"] = "VEC2";
bufferViewIndex++; bufferViewIndex++;
} }
@ -205,15 +205,15 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object,
m_json["samplers"][0]["minFilter"] = 9987; m_json["samplers"][0]["minFilter"] = 9987;
m_json["samplers"][0]["wrapS"] = 33648; m_json["samplers"][0]["wrapS"] = 33648;
m_json["samplers"][0]["wrapT"] = 33648; m_json["samplers"][0]["wrapT"] = 33648;
int imageIndex = 0; int imageIndex = 0;
int textureIndex = 0; int textureIndex = 0;
// Images should be put in the end of the buffer, because we are not using accessors // Images should be put in the end of the buffer, because we are not using accessors
if (nullptr != textureImage) { if (nullptr != textureImage) {
m_json["textures"][textureIndex]["sampler"] = 0; m_json["textures"][textureIndex]["sampler"] = 0;
m_json["textures"][textureIndex]["source"] = imageIndex; m_json["textures"][textureIndex]["source"] = imageIndex;
bufferViewFromOffset = (int)m_binByteArray.size(); bufferViewFromOffset = (int)m_binByteArray.size();
m_json["bufferViews"][bufferViewIndex]["buffer"] = 0; m_json["bufferViews"][bufferViewIndex]["buffer"] = 0;
m_json["bufferViews"][bufferViewIndex]["byteOffset"] = bufferViewFromOffset; m_json["bufferViews"][bufferViewIndex]["byteOffset"] = bufferViewFromOffset;
@ -226,14 +226,14 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object,
m_json["images"][imageIndex]["bufferView"] = bufferViewIndex; m_json["images"][imageIndex]["bufferView"] = bufferViewIndex;
m_json["images"][imageIndex]["mimeType"] = "image/png"; m_json["images"][imageIndex]["mimeType"] = "image/png";
bufferViewIndex++; bufferViewIndex++;
imageIndex++; imageIndex++;
textureIndex++; textureIndex++;
} }
if (nullptr != normalImage) { if (nullptr != normalImage) {
m_json["textures"][textureIndex]["sampler"] = 0; m_json["textures"][textureIndex]["sampler"] = 0;
m_json["textures"][textureIndex]["source"] = imageIndex; m_json["textures"][textureIndex]["source"] = imageIndex;
bufferViewFromOffset = (int)m_binByteArray.size(); bufferViewFromOffset = (int)m_binByteArray.size();
m_json["bufferViews"][bufferViewIndex]["buffer"] = 0; m_json["bufferViews"][bufferViewIndex]["buffer"] = 0;
m_json["bufferViews"][bufferViewIndex]["byteOffset"] = bufferViewFromOffset; m_json["bufferViews"][bufferViewIndex]["byteOffset"] = bufferViewFromOffset;
@ -246,14 +246,14 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object,
m_json["images"][imageIndex]["bufferView"] = bufferViewIndex; m_json["images"][imageIndex]["bufferView"] = bufferViewIndex;
m_json["images"][imageIndex]["mimeType"] = "image/png"; m_json["images"][imageIndex]["mimeType"] = "image/png";
bufferViewIndex++; bufferViewIndex++;
imageIndex++; imageIndex++;
textureIndex++; textureIndex++;
} }
if (nullptr != ormImage) { if (nullptr != ormImage) {
m_json["textures"][textureIndex]["sampler"] = 0; m_json["textures"][textureIndex]["sampler"] = 0;
m_json["textures"][textureIndex]["source"] = imageIndex; m_json["textures"][textureIndex]["source"] = imageIndex;
bufferViewFromOffset = (int)m_binByteArray.size(); bufferViewFromOffset = (int)m_binByteArray.size();
m_json["bufferViews"][bufferViewIndex]["buffer"] = 0; m_json["bufferViews"][bufferViewIndex]["buffer"] = 0;
m_json["bufferViews"][bufferViewIndex]["byteOffset"] = bufferViewFromOffset; m_json["bufferViews"][bufferViewIndex]["byteOffset"] = bufferViewFromOffset;
@ -266,13 +266,13 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object,
m_json["images"][imageIndex]["bufferView"] = bufferViewIndex; m_json["images"][imageIndex]["bufferView"] = bufferViewIndex;
m_json["images"][imageIndex]["mimeType"] = "image/png"; m_json["images"][imageIndex]["mimeType"] = "image/png";
bufferViewIndex++; bufferViewIndex++;
imageIndex++; imageIndex++;
textureIndex++; textureIndex++;
} }
m_json["buffers"][0]["byteLength"] = m_binByteArray.size(); m_json["buffers"][0]["byteLength"] = m_binByteArray.size();
auto jsonString = m_enableComment ? m_json.dump(4) : m_json.dump(); auto jsonString = m_enableComment ? m_json.dump(4) : m_json.dump();
jsonStream.writeRawData(jsonString.data(), jsonString.size()); jsonStream.writeRawData(jsonString.data(), jsonString.size());
alignJson(); alignJson();
@ -287,50 +287,48 @@ bool GlbFileWriter::save()
QDataStream output(&file); QDataStream output(&file);
output.setFloatingPointPrecision(QDataStream::SinglePrecision); output.setFloatingPointPrecision(QDataStream::SinglePrecision);
output.setByteOrder(QDataStream::LittleEndian); output.setByteOrder(QDataStream::LittleEndian);
uint32_t headerSize = 12; uint32_t headerSize = 12;
uint32_t chunk0DescriptionSize = 8; uint32_t chunk0DescriptionSize = 8;
uint32_t chunk1DescriptionSize = 8; uint32_t chunk1DescriptionSize = 8;
uint32_t fileSize = headerSize + uint32_t fileSize = headerSize + chunk0DescriptionSize + m_jsonByteArray.size() + chunk1DescriptionSize + m_binByteArray.size();
chunk0DescriptionSize + m_jsonByteArray.size() +
chunk1DescriptionSize + m_binByteArray.size();
qDebug() << "Chunk 0 data size:" << m_jsonByteArray.size(); qDebug() << "Chunk 0 data size:" << m_jsonByteArray.size();
qDebug() << "Chunk 1 data size:" << m_binByteArray.size(); qDebug() << "Chunk 1 data size:" << m_binByteArray.size();
qDebug() << "File size:" << fileSize; qDebug() << "File size:" << fileSize;
//////////// Header //////////// //////////// Header ////////////
// magic // magic
output << (uint32_t)0x46546C67; output << (uint32_t)0x46546C67;
// version // version
output << (uint32_t)0x00000002; output << (uint32_t)0x00000002;
// length // length
output << (uint32_t)fileSize; output << (uint32_t)fileSize;
//////////// Chunk 0 (Json) //////////// //////////// Chunk 0 (Json) ////////////
// length // length
output << (uint32_t)m_jsonByteArray.size(); output << (uint32_t)m_jsonByteArray.size();
// type // type
output << (uint32_t)0x4E4F534A; output << (uint32_t)0x4E4F534A;
// data // data
output.writeRawData(m_jsonByteArray.data(), m_jsonByteArray.size()); output.writeRawData(m_jsonByteArray.data(), m_jsonByteArray.size());
//////////// Chunk 1 (Binary Buffer) /// //////////// Chunk 1 (Binary Buffer) ///
// length // length
output << (uint32_t)m_binByteArray.size(); output << (uint32_t)m_binByteArray.size();
// type // type
output << (uint32_t)0x004E4942; output << (uint32_t)0x004E4942;
// data // data
output.writeRawData(m_binByteArray.data(), m_binByteArray.size()); output.writeRawData(m_binByteArray.data(), m_binByteArray.size());
return true; return true;
} }

View File

@ -1,35 +1,37 @@
#ifndef DUST3D_APPLICATION_GLB_FILE_H_ #ifndef DUST3D_APPLICATION_GLB_FILE_H_
#define DUST3D_APPLICATION_GLB_FILE_H_ #define DUST3D_APPLICATION_GLB_FILE_H_
#include <QObject>
#include <QString>
#include <QByteArray>
#include <QMatrix4x4>
#include <vector>
#include <QQuaternion>
#include <QImage>
#include <dust3d/base/object.h>
#include "json.hpp"
#include "document.h" #include "document.h"
#include "json.hpp"
#include <QByteArray>
#include <QImage>
#include <QMatrix4x4>
#include <QObject>
#include <QQuaternion>
#include <QString>
#include <dust3d/base/object.h>
#include <vector>
class GlbFileWriter : public QObject class GlbFileWriter : public QObject {
{
Q_OBJECT Q_OBJECT
public: public:
GlbFileWriter(dust3d::Object &object, GlbFileWriter(dust3d::Object& object,
const QString &filename, const QString& filename,
QImage *textureImage=nullptr, QImage* textureImage = nullptr,
QImage *normalImage=nullptr, QImage* normalImage = nullptr,
QImage *ormImage=nullptr); QImage* ormImage = nullptr);
bool save(); bool save();
private: private:
QString m_filename; QString m_filename;
bool m_outputNormal = true; bool m_outputNormal = true;
bool m_outputUv = true; bool m_outputUv = true;
QByteArray m_binByteArray; QByteArray m_binByteArray;
QByteArray m_jsonByteArray; QByteArray m_jsonByteArray;
private: private:
nlohmann::json m_json; nlohmann::json m_json;
public: public:
static bool m_enableComment; static bool m_enableComment;
}; };

View File

@ -5,47 +5,47 @@ GraphicsContainerWidget::GraphicsContainerWidget()
setMouseTracking(true); setMouseTracking(true);
} }
void GraphicsContainerWidget::resizeEvent(QResizeEvent *event) void GraphicsContainerWidget::resizeEvent(QResizeEvent* event)
{ {
if (m_graphicsWidget && m_graphicsWidget->size() != event->size()) if (m_graphicsWidget && m_graphicsWidget->size() != event->size())
emit containerSizeChanged(event->size()); emit containerSizeChanged(event->size());
} }
void GraphicsContainerWidget::mousePressEvent(QMouseEvent *event) void GraphicsContainerWidget::mousePressEvent(QMouseEvent* event)
{ {
if (m_modelWidget) if (m_modelWidget)
m_modelWidget->inputMousePressEventFromOtherWidget(event); m_modelWidget->inputMousePressEventFromOtherWidget(event);
} }
void GraphicsContainerWidget::mouseMoveEvent(QMouseEvent *event) void GraphicsContainerWidget::mouseMoveEvent(QMouseEvent* event)
{ {
if (m_modelWidget) if (m_modelWidget)
m_modelWidget->inputMouseMoveEventFromOtherWidget(event); m_modelWidget->inputMouseMoveEventFromOtherWidget(event);
} }
void GraphicsContainerWidget::mouseReleaseEvent(QMouseEvent *event) void GraphicsContainerWidget::mouseReleaseEvent(QMouseEvent* event)
{ {
if (m_modelWidget) if (m_modelWidget)
m_modelWidget->inputMouseReleaseEventFromOtherWidget(event); m_modelWidget->inputMouseReleaseEventFromOtherWidget(event);
} }
void GraphicsContainerWidget::wheelEvent(QWheelEvent *event) void GraphicsContainerWidget::wheelEvent(QWheelEvent* event)
{ {
if (m_graphicsWidget) { if (m_graphicsWidget) {
m_graphicsWidget->inputWheelEventFromOtherWidget(event); m_graphicsWidget->inputWheelEventFromOtherWidget(event);
return; return;
} }
if (m_modelWidget) if (m_modelWidget)
m_modelWidget->inputWheelEventFromOtherWidget(event); m_modelWidget->inputWheelEventFromOtherWidget(event);
} }
void GraphicsContainerWidget::setGraphicsWidget(SkeletonGraphicsWidget *graphicsWidget) void GraphicsContainerWidget::setGraphicsWidget(SkeletonGraphicsWidget* graphicsWidget)
{ {
m_graphicsWidget = graphicsWidget; m_graphicsWidget = graphicsWidget;
} }
void GraphicsContainerWidget::setModelWidget(ModelWidget *modelWidget) void GraphicsContainerWidget::setModelWidget(ModelWidget* modelWidget)
{ {
m_modelWidget = modelWidget; m_modelWidget = modelWidget;
} }

View File

@ -1,31 +1,33 @@
#ifndef DUST3D_APPLICATION_GRAPHICS_CONTAINER_WIDGET_H_ #ifndef DUST3D_APPLICATION_GRAPHICS_CONTAINER_WIDGET_H_
#define DUST3D_APPLICATION_GRAPHICS_CONTAINER_WIDGET_H_ #define DUST3D_APPLICATION_GRAPHICS_CONTAINER_WIDGET_H_
#include <QWidget>
#include <QResizeEvent>
#include <QMouseEvent>
#include <QWheelEvent>
#include "model_widget.h" #include "model_widget.h"
#include "skeleton_graphics_widget.h" #include "skeleton_graphics_widget.h"
#include <QMouseEvent>
#include <QResizeEvent>
#include <QWheelEvent>
#include <QWidget>
class GraphicsContainerWidget : public QWidget class GraphicsContainerWidget : public QWidget {
{
Q_OBJECT Q_OBJECT
signals: signals:
void containerSizeChanged(QSize size); void containerSizeChanged(QSize size);
public: public:
GraphicsContainerWidget(); GraphicsContainerWidget();
void setGraphicsWidget(SkeletonGraphicsWidget *graphicsWidget); void setGraphicsWidget(SkeletonGraphicsWidget* graphicsWidget);
void setModelWidget(ModelWidget *modelWidget); void setModelWidget(ModelWidget* modelWidget);
protected: protected:
void resizeEvent(QResizeEvent *event) override; void resizeEvent(QResizeEvent* event) override;
void mousePressEvent(QMouseEvent *event) override; void mousePressEvent(QMouseEvent* event) override;
void mouseMoveEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent* event) override;
void mouseReleaseEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent* event) override;
void wheelEvent(QWheelEvent *event) override; void wheelEvent(QWheelEvent* event) override;
private: private:
ModelWidget *m_modelWidget = nullptr; ModelWidget* m_modelWidget = nullptr;
SkeletonGraphicsWidget *m_graphicsWidget = nullptr; SkeletonGraphicsWidget* m_graphicsWidget = nullptr;
}; };
#endif #endif

View File

@ -1,7 +1,7 @@
#include "horizontal_line_widget.h" #include "horizontal_line_widget.h"
HorizontalLineWidget::HorizontalLineWidget() : HorizontalLineWidget::HorizontalLineWidget()
QWidget() : QWidget()
{ {
setFixedHeight(1); setFixedHeight(1);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

View File

@ -3,8 +3,7 @@
#include <QWidget> #include <QWidget>
class HorizontalLineWidget : public QWidget class HorizontalLineWidget : public QWidget {
{
Q_OBJECT Q_OBJECT
public: public:
HorizontalLineWidget(); HorizontalLineWidget();

View File

@ -1,19 +1,18 @@
#include <map> #include "image_forever.h"
#include <QMutex> #include <QMutex>
#include <QMutexLocker> #include <QMutexLocker>
#include <QtCore/qbuffer.h> #include <QtCore/qbuffer.h>
#include "image_forever.h" #include <map>
struct ImageForeverItem struct ImageForeverItem {
{ QImage* image;
QImage *image;
dust3d::Uuid id; dust3d::Uuid id;
QByteArray *imageByteArray; QByteArray* imageByteArray;
}; };
static std::map<dust3d::Uuid, ImageForeverItem> g_foreverMap; static std::map<dust3d::Uuid, ImageForeverItem> g_foreverMap;
static QMutex g_mapMutex; static QMutex g_mapMutex;
const QImage *ImageForever::get(const dust3d::Uuid &id) const QImage* ImageForever::get(const dust3d::Uuid& id)
{ {
QMutexLocker locker(&g_mapMutex); QMutexLocker locker(&g_mapMutex);
auto findResult = g_foreverMap.find(id); auto findResult = g_foreverMap.find(id);
@ -22,7 +21,7 @@ const QImage *ImageForever::get(const dust3d::Uuid &id)
return findResult->second.image; return findResult->second.image;
} }
void ImageForever::copy(const dust3d::Uuid &id, QImage &image) void ImageForever::copy(const dust3d::Uuid& id, QImage& image)
{ {
QMutexLocker locker(&g_mapMutex); QMutexLocker locker(&g_mapMutex);
auto findResult = g_foreverMap.find(id); auto findResult = g_foreverMap.find(id);
@ -31,7 +30,7 @@ void ImageForever::copy(const dust3d::Uuid &id, QImage &image)
image = *findResult->second.image; image = *findResult->second.image;
} }
const QByteArray *ImageForever::getPngByteArray(const dust3d::Uuid &id) const QByteArray* ImageForever::getPngByteArray(const dust3d::Uuid& id)
{ {
QMutexLocker locker(&g_mapMutex); QMutexLocker locker(&g_mapMutex);
auto findResult = g_foreverMap.find(id); auto findResult = g_foreverMap.find(id);
@ -40,7 +39,7 @@ const QByteArray *ImageForever::getPngByteArray(const dust3d::Uuid &id)
return findResult->second.imageByteArray; return findResult->second.imageByteArray;
} }
dust3d::Uuid ImageForever::add(const QImage *image, dust3d::Uuid toId) dust3d::Uuid ImageForever::add(const QImage* image, dust3d::Uuid toId)
{ {
QMutexLocker locker(&g_mapMutex); QMutexLocker locker(&g_mapMutex);
if (nullptr == image) if (nullptr == image)
@ -48,16 +47,16 @@ dust3d::Uuid ImageForever::add(const QImage *image, dust3d::Uuid toId)
dust3d::Uuid newId = toId.isNull() ? dust3d::Uuid::createUuid() : toId; dust3d::Uuid newId = toId.isNull() ? dust3d::Uuid::createUuid() : toId;
if (g_foreverMap.find(newId) != g_foreverMap.end()) if (g_foreverMap.find(newId) != g_foreverMap.end())
return newId; return newId;
QImage *newImage = new QImage(*image); QImage* newImage = new QImage(*image);
QByteArray *imageByteArray = new QByteArray(); QByteArray* imageByteArray = new QByteArray();
QBuffer pngBuffer(imageByteArray); QBuffer pngBuffer(imageByteArray);
pngBuffer.open(QIODevice::WriteOnly); pngBuffer.open(QIODevice::WriteOnly);
newImage->save(&pngBuffer, "PNG"); newImage->save(&pngBuffer, "PNG");
g_foreverMap[newId] = {newImage, newId, imageByteArray}; g_foreverMap[newId] = { newImage, newId, imageByteArray };
return newId; return newId;
} }
void ImageForever::remove(const dust3d::Uuid &id) void ImageForever::remove(const dust3d::Uuid& id)
{ {
QMutexLocker locker(&g_mapMutex); QMutexLocker locker(&g_mapMutex);
auto findImage = g_foreverMap.find(id); auto findImage = g_foreverMap.find(id);

View File

@ -1,18 +1,17 @@
#ifndef DUST3D_APPLICATION_IMAGE_FOREVER_H_ #ifndef DUST3D_APPLICATION_IMAGE_FOREVER_H_
#define DUST3D_APPLICATION_IMAGE_FOREVER_H_ #define DUST3D_APPLICATION_IMAGE_FOREVER_H_
#include <QImage>
#include <QByteArray> #include <QByteArray>
#include <QImage>
#include <dust3d/base/uuid.h> #include <dust3d/base/uuid.h>
class ImageForever class ImageForever {
{
public: public:
static const QImage *get(const dust3d::Uuid &id); static const QImage* get(const dust3d::Uuid& id);
static void copy(const dust3d::Uuid &id, QImage &image); static void copy(const dust3d::Uuid& id, QImage& image);
static const QByteArray *getPngByteArray(const dust3d::Uuid &id); static const QByteArray* getPngByteArray(const dust3d::Uuid& id);
static dust3d::Uuid add(const QImage *image, dust3d::Uuid toId=dust3d::Uuid()); static dust3d::Uuid add(const QImage* image, dust3d::Uuid toId = dust3d::Uuid());
static void remove(const dust3d::Uuid &id); static void remove(const dust3d::Uuid& id);
}; };
#endif #endif

View File

@ -1,28 +1,28 @@
#include <QPainter>
#include "image_preview_widget.h" #include "image_preview_widget.h"
#include <QPainter>
ImagePreviewWidget::ImagePreviewWidget(QWidget *parent) : ImagePreviewWidget::ImagePreviewWidget(QWidget* parent)
QWidget(parent) : QWidget(parent)
{ {
} }
void ImagePreviewWidget::updateImage(const QImage &image) void ImagePreviewWidget::updateImage(const QImage& image)
{ {
m_image = image; m_image = image;
update(); update();
} }
void ImagePreviewWidget::updateBackgroundColor(const QColor &color) void ImagePreviewWidget::updateBackgroundColor(const QColor& color)
{ {
m_backgroundColor = color; m_backgroundColor = color;
} }
void ImagePreviewWidget::mousePressEvent(QMouseEvent *event) void ImagePreviewWidget::mousePressEvent(QMouseEvent* event)
{ {
emit clicked(); emit clicked();
} }
void ImagePreviewWidget::paintEvent(QPaintEvent *event) void ImagePreviewWidget::paintEvent(QPaintEvent* event)
{ {
QPainter painter(this); QPainter painter(this);
if (!m_image.isNull()) if (!m_image.isNull())
@ -30,4 +30,3 @@ void ImagePreviewWidget::paintEvent(QPaintEvent *event)
else else
painter.fillRect(QRect(0, 0, width(), height()), QBrush(m_backgroundColor)); painter.fillRect(QRect(0, 0, width(), height()), QBrush(m_backgroundColor));
} }

View File

@ -1,30 +1,30 @@
#ifndef DUST3D_APPLICATION_IMAGE_PREVIEW_WIDGET_H_ #ifndef DUST3D_APPLICATION_IMAGE_PREVIEW_WIDGET_H_
#define DUST3D_APPLICATION_IMAGE_PREVIEW_WIDGET_H_ #define DUST3D_APPLICATION_IMAGE_PREVIEW_WIDGET_H_
#include <QWidget>
#include <QImage> #include <QImage>
#include <QPaintEvent>
#include <QMouseEvent> #include <QMouseEvent>
#include <QPaintEvent>
#include <QWidget>
class ImagePreviewWidget : public QWidget class ImagePreviewWidget : public QWidget {
{
Q_OBJECT Q_OBJECT
signals: signals:
void clicked(); void clicked();
public: public:
ImagePreviewWidget(QWidget *parent=nullptr); ImagePreviewWidget(QWidget* parent = nullptr);
void updateImage(const QImage &image); void updateImage(const QImage& image);
void updateBackgroundColor(const QColor &color); void updateBackgroundColor(const QColor& color);
protected: protected:
void paintEvent(QPaintEvent *event); void paintEvent(QPaintEvent* event);
void mousePressEvent(QMouseEvent *event); void mousePressEvent(QMouseEvent* event);
private: private:
QImage m_image; QImage m_image;
QColor m_backgroundColor; QColor m_backgroundColor;
void resizeImage(QImage *image, const QSize &newSize); void resizeImage(QImage* image, const QSize& newSize);
}; };
#endif #endif

View File

@ -1,25 +1,25 @@
#include <QHBoxLayout>
#include "info_label.h" #include "info_label.h"
#include "theme.h" #include "theme.h"
#include <QHBoxLayout>
InfoLabel::InfoLabel(const QString &text, QWidget *parent) : InfoLabel::InfoLabel(const QString& text, QWidget* parent)
QWidget(parent) : QWidget(parent)
{ {
m_icon = new QLabel(QChar(fa::infocircle)); m_icon = new QLabel(QChar(fa::infocircle));
Theme::initAwesomeLabel(m_icon); Theme::initAwesomeLabel(m_icon);
m_label = new QLabel(text); m_label = new QLabel(text);
m_label->setWordWrap(true); m_label->setWordWrap(true);
QHBoxLayout *mainLayout = new QHBoxLayout; QHBoxLayout* mainLayout = new QHBoxLayout;
mainLayout->addWidget(m_icon); mainLayout->addWidget(m_icon);
mainLayout->addWidget(m_label); mainLayout->addWidget(m_label);
mainLayout->addStretch(); mainLayout->addStretch();
setLayout(mainLayout); setLayout(mainLayout);
} }
void InfoLabel::setText(const QString &text) void InfoLabel::setText(const QString& text)
{ {
m_label->setText(text); m_label->setText(text);
} }

View File

@ -1,18 +1,18 @@
#ifndef DUST3D_APPLICATION_INFO_LABEL_H_ #ifndef DUST3D_APPLICATION_INFO_LABEL_H_
#define DUST3D_APPLICATION_INFO_LABEL_H_ #define DUST3D_APPLICATION_INFO_LABEL_H_
#include <QLabel>
#include <QIcon> #include <QIcon>
#include <QLabel>
#include <QWidget> #include <QWidget>
class InfoLabel : public QWidget class InfoLabel : public QWidget {
{
public: public:
InfoLabel(const QString &text=QString(), QWidget *parent=nullptr); InfoLabel(const QString& text = QString(), QWidget* parent = nullptr);
void setText(const QString &text); void setText(const QString& text);
private: private:
QLabel *m_label = nullptr; QLabel* m_label = nullptr;
QLabel *m_icon = nullptr; QLabel* m_icon = nullptr;
}; };
#endif #endif

View File

@ -1,11 +1,11 @@
#include <QtWidgets> #include "int_number_widget.h"
#include "theme.h"
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QVBoxLayout> #include <QVBoxLayout>
#include "theme.h" #include <QtWidgets>
#include "int_number_widget.h"
IntNumberWidget::IntNumberWidget(QWidget *parent, bool singleLine) : IntNumberWidget::IntNumberWidget(QWidget* parent, bool singleLine)
QWidget(parent) : QWidget(parent)
{ {
m_slider = new QSlider(Qt::Horizontal, this); m_slider = new QSlider(Qt::Horizontal, this);
m_slider->setRange(0, 100); m_slider->setRange(0, 100);
@ -18,8 +18,8 @@ IntNumberWidget::IntNumberWidget(QWidget *parent, bool singleLine) :
updateValueLabel(value); updateValueLabel(value);
emit valueChanged(value); emit valueChanged(value);
}); });
QBoxLayout *layout = nullptr; QBoxLayout* layout = nullptr;
if (singleLine) { if (singleLine) {
layout = new QHBoxLayout(this); layout = new QHBoxLayout(this);
layout->setMargin(2); layout->setMargin(2);
@ -42,7 +42,7 @@ void IntNumberWidget::updateValueLabel(int value)
m_label->setText(m_itemName + ": " + valueString); m_label->setText(m_itemName + ": " + valueString);
} }
void IntNumberWidget::setItemName(const QString &name) void IntNumberWidget::setItemName(const QString& name)
{ {
m_itemName = name; m_itemName = name;
updateValueLabel(value()); updateValueLabel(value());

View File

@ -6,14 +6,13 @@
QT_FORWARD_DECLARE_CLASS(QLabel) QT_FORWARD_DECLARE_CLASS(QLabel)
QT_FORWARD_DECLARE_CLASS(QSlider) QT_FORWARD_DECLARE_CLASS(QSlider)
class IntNumberWidget : public QWidget class IntNumberWidget : public QWidget {
{
Q_OBJECT Q_OBJECT
public: public:
explicit IntNumberWidget(QWidget *parent = nullptr, bool singleLine=true); explicit IntNumberWidget(QWidget* parent = nullptr, bool singleLine = true);
void setRange(int min, int max); void setRange(int min, int max);
int value() const; int value() const;
void setItemName(const QString &name); void setItemName(const QString& name);
public slots: public slots:
void increaseValue(); void increaseValue();
@ -22,13 +21,13 @@ public slots:
signals: signals:
void valueChanged(int value); void valueChanged(int value);
private: private:
void updateValueLabel(int value); void updateValueLabel(int value);
private: private:
QLabel *m_label = nullptr; QLabel* m_label = nullptr;
QSlider *m_slider = nullptr; QSlider* m_slider = nullptr;
QString m_itemName; QString m_itemName;
}; };

View File

@ -1,17 +1,17 @@
#include <QMetaType>
#include <QDir>
#include "log_browser.h" #include "log_browser.h"
#include "log_browser_dialog.h" #include "log_browser_dialog.h"
#include <QDir>
#include <QMetaType>
bool LogBrowser::m_enableOutputToFile = true; bool LogBrowser::m_enableOutputToFile = true;
LogBrowser::LogBrowser(QObject *parent) : LogBrowser::LogBrowser(QObject* parent)
QObject(parent) : QObject(parent)
{ {
qRegisterMetaType<QtMsgType>("QtMsgType"); qRegisterMetaType<QtMsgType>("QtMsgType");
m_browserDialog = new LogBrowserDialog; m_browserDialog = new LogBrowserDialog;
connect(this, &LogBrowser::sendMessage, m_browserDialog, &LogBrowserDialog::outputMessage, Qt::QueuedConnection); connect(this, &LogBrowser::sendMessage, m_browserDialog, &LogBrowserDialog::outputMessage, Qt::QueuedConnection);
if (m_enableOutputToFile) { if (m_enableOutputToFile) {
QString filePath = "application.log"; QString filePath = "application.log";
m_outputTo = fopen(filePath.toUtf8().constData(), "w"); m_outputTo = fopen(filePath.toUtf8().constData(), "w");
@ -42,7 +42,7 @@ bool LogBrowser::isDialogVisible()
return m_browserDialog->isVisible(); return m_browserDialog->isVisible();
} }
void LogBrowser::outputMessage(QtMsgType type, const QString &msg, const QString &source, int line) void LogBrowser::outputMessage(QtMsgType type, const QString& msg, const QString& source, int line)
{ {
if (m_outputTo) { if (m_outputTo) {
fprintf(m_outputTo, "[%s:%d]: %s\n", source.toUtf8().constData(), line, msg.toUtf8().constData()); fprintf(m_outputTo, "[%s:%d]: %s\n", source.toUtf8().constData(), line, msg.toUtf8().constData());

View File

@ -6,25 +6,24 @@
class LogBrowserDialog; class LogBrowserDialog;
class LogBrowser : public QObject class LogBrowser : public QObject {
{
Q_OBJECT Q_OBJECT
public: public:
explicit LogBrowser(QObject *parent=0); explicit LogBrowser(QObject* parent = 0);
~LogBrowser(); ~LogBrowser();
public slots: public slots:
void outputMessage(QtMsgType type, const QString &msg, const QString &source, int line); void outputMessage(QtMsgType type, const QString& msg, const QString& source, int line);
void showDialog(); void showDialog();
void hideDialog(); void hideDialog();
bool isDialogVisible(); bool isDialogVisible();
signals: signals:
void sendMessage(QtMsgType type, const QString &msg, const QString &source, int line); void sendMessage(QtMsgType type, const QString& msg, const QString& source, int line);
private: private:
LogBrowserDialog *m_browserDialog = nullptr; LogBrowserDialog* m_browserDialog = nullptr;
FILE *m_outputTo = nullptr; FILE* m_outputTo = nullptr;
static bool m_enableOutputToFile; static bool m_enableOutputToFile;
}; };

View File

@ -1,30 +1,30 @@
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QTextBrowser>
#include <QPushButton>
#include <QFileDialog>
#include <QDir>
#include <QFile>
#include <QMessageBox>
#include <QTextStream>
#include <QCloseEvent>
#include <QKeyEvent>
#include "version.h"
#include "log_browser_dialog.h" #include "log_browser_dialog.h"
#include "document_window.h" #include "document_window.h"
#include "version.h"
#include <QCloseEvent>
#include <QDir>
#include <QFile>
#include <QFileDialog>
#include <QHBoxLayout>
#include <QKeyEvent>
#include <QMessageBox>
#include <QPushButton>
#include <QTextBrowser>
#include <QTextStream>
#include <QVBoxLayout>
LogBrowserDialog::LogBrowserDialog(QWidget *parent) : LogBrowserDialog::LogBrowserDialog(QWidget* parent)
QDialog(parent) : QDialog(parent)
{ {
setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
QVBoxLayout *layout = new QVBoxLayout; QVBoxLayout* layout = new QVBoxLayout;
setLayout(layout); setLayout(layout);
m_browser = new QTextBrowser(this); m_browser = new QTextBrowser(this);
layout->addWidget(m_browser); layout->addWidget(m_browser);
QHBoxLayout *buttonLayout = new QHBoxLayout; QHBoxLayout* buttonLayout = new QHBoxLayout;
buttonLayout->setContentsMargins(0, 0, 0, 0); buttonLayout->setContentsMargins(0, 0, 0, 0);
layout->addLayout(buttonLayout); layout->addLayout(buttonLayout);
@ -41,20 +41,17 @@ LogBrowserDialog::LogBrowserDialog(QWidget *parent) :
connect(m_saveButton, SIGNAL(clicked()), this, SLOT(save())); connect(m_saveButton, SIGNAL(clicked()), this, SLOT(save()));
resize(600, 300); resize(600, 300);
setWindowTitle(applicationTitle(tr("Debug"))); setWindowTitle(applicationTitle(tr("Debug")));
hide(); hide();
} }
LogBrowserDialog::~LogBrowserDialog() LogBrowserDialog::~LogBrowserDialog()
{ {
} }
void LogBrowserDialog::outputMessage(QtMsgType type, const QString& msg, const QString& source, int line)
void LogBrowserDialog::outputMessage(QtMsgType type, const QString &msg, const QString &source, int line)
{ {
switch (type) { switch (type) {
case QtDebugMsg: case QtDebugMsg:
@ -79,7 +76,6 @@ void LogBrowserDialog::outputMessage(QtMsgType type, const QString &msg, const Q
} }
} }
void LogBrowserDialog::save() void LogBrowserDialog::save()
{ {
QString saveFileName = QFileDialog::getSaveFileName(this, QString saveFileName = QFileDialog::getSaveFileName(this,
@ -95,8 +91,8 @@ void LogBrowserDialog::save()
QMessageBox::warning(this, QMessageBox::warning(this,
tr("Error"), tr("Error"),
QString(tr("<nobr>File '%1'<br/>cannot be opened for writing.<br/><br/>" QString(tr("<nobr>File '%1'<br/>cannot be opened for writing.<br/><br/>"
"The log output could <b>not</b> be saved!</nobr>")) "The log output could <b>not</b> be saved!</nobr>"))
.arg(saveFileName)); .arg(saveFileName));
return; return;
} }
@ -105,7 +101,7 @@ void LogBrowserDialog::save()
file.close(); file.close();
} }
void LogBrowserDialog::closeEvent(QCloseEvent *e) void LogBrowserDialog::closeEvent(QCloseEvent* e)
{ {
if (0 == DocumentWindow::total()) { if (0 == DocumentWindow::total()) {
e->accept(); e->accept();
@ -115,7 +111,7 @@ void LogBrowserDialog::closeEvent(QCloseEvent *e)
hide(); hide();
} }
void LogBrowserDialog::keyPressEvent(QKeyEvent *e) void LogBrowserDialog::keyPressEvent(QKeyEvent* e)
{ {
e->ignore(); e->ignore();
} }

View File

@ -6,26 +6,25 @@
class QTextBrowser; class QTextBrowser;
class QPushButton; class QPushButton;
class LogBrowserDialog : public QDialog class LogBrowserDialog : public QDialog {
{
Q_OBJECT Q_OBJECT
public: public:
LogBrowserDialog(QWidget *parent = 0); LogBrowserDialog(QWidget* parent = 0);
~LogBrowserDialog(); ~LogBrowserDialog();
public slots: public slots:
void outputMessage(QtMsgType type, const QString &msg, const QString &source, int line); void outputMessage(QtMsgType type, const QString& msg, const QString& source, int line);
protected slots: protected slots:
void save(); void save();
protected: protected:
virtual void keyPressEvent(QKeyEvent *e); virtual void keyPressEvent(QKeyEvent* e);
virtual void closeEvent(QCloseEvent *e); virtual void closeEvent(QCloseEvent* e);
QTextBrowser *m_browser; QTextBrowser* m_browser;
QPushButton *m_clearButton; QPushButton* m_clearButton;
QPushButton *m_saveButton; QPushButton* m_saveButton;
}; };
#endif #endif

View File

@ -1,41 +1,40 @@
#include <QApplication>
#include <QSurfaceFormat>
#include <QDebug>
#include <iostream>
#include <cstdio>
#include <dust3d/base/string.h>
#include "document_window.h"
#include "document.h" #include "document.h"
#include "document_window.h"
#include "theme.h" #include "theme.h"
#include "version.h" #include "version.h"
#include <QApplication>
#include <QDebug>
#include <QSurfaceFormat>
#include <cstdio>
#include <dust3d/base/string.h>
#include <iostream>
int main(int argc, char *argv[]) int main(int argc, char* argv[])
{ {
QApplication app(argc, argv); QApplication app(argc, argv);
QSurfaceFormat format = QSurfaceFormat::defaultFormat(); QSurfaceFormat format = QSurfaceFormat::defaultFormat();
format.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile); format.setProfile(QSurfaceFormat::OpenGLContextProfile::CoreProfile);
format.setVersion(3, 3); format.setVersion(3, 3);
QSurfaceFormat::setDefaultFormat(format); QSurfaceFormat::setDefaultFormat(format);
Theme::initialize(); Theme::initialize();
QCoreApplication::setApplicationName(APP_NAME); QCoreApplication::setApplicationName(APP_NAME);
QCoreApplication::setOrganizationName(APP_COMPANY); QCoreApplication::setOrganizationName(APP_COMPANY);
QCoreApplication::setOrganizationDomain(APP_HOMEPAGE_URL); QCoreApplication::setOrganizationDomain(APP_HOMEPAGE_URL);
//freopen("dust3d.log", "w", stdout); //freopen("dust3d.log", "w", stdout);
//setvbuf(stdout, 0, _IONBF, 0); //setvbuf(stdout, 0, _IONBF, 0);
DocumentWindow *firstWindow = DocumentWindow::createDocumentWindow(); DocumentWindow* firstWindow = DocumentWindow::createDocumentWindow();
QStringList openFileList; QStringList openFileList;
QStringList waitingExportList; QStringList waitingExportList;
bool toggleColor = false; bool toggleColor = false;
for (int i = 1; i < argc; ++i) { for (int i = 1; i < argc; ++i) {
if ('-' == argv[i][0]) { if ('-' == argv[i][0]) {
if (0 == strcmp(argv[i], "-output") || if (0 == strcmp(argv[i], "-output") || 0 == strcmp(argv[i], "-o")) {
0 == strcmp(argv[i], "-o")) {
++i; ++i;
if (i < argc) if (i < argc)
waitingExportList.append(argv[i]); waitingExportList.append(argv[i]);
@ -55,12 +54,12 @@ int main(int argc, char *argv[])
continue; continue;
} }
} }
int finishedExportFileNum = 0; int finishedExportFileNum = 0;
int totalExportFileNum = 0; int totalExportFileNum = 0;
int succeedExportNum = 0; int succeedExportNum = 0;
int exitCode = -1; int exitCode = -1;
std::vector<DocumentWindow *> windowList; std::vector<DocumentWindow*> windowList;
auto checkToSafelyExit = [&]() { auto checkToSafelyExit = [&]() {
if (-1 == exitCode) if (-1 == exitCode)
return; return;
@ -76,17 +75,16 @@ int main(int argc, char *argv[])
windowList.push_back(DocumentWindow::createDocumentWindow()); windowList.push_back(DocumentWindow::createDocumentWindow());
} }
if (toggleColor) { if (toggleColor) {
for (auto &it: windowList) for (auto& it : windowList)
it->toggleRenderColor(); it->toggleRenderColor();
} }
if (!waitingExportList.empty() && if (!waitingExportList.empty() && openFileList.size() == 1) {
openFileList.size() == 1) {
totalExportFileNum = openFileList.size() * waitingExportList.size(); totalExportFileNum = openFileList.size() * waitingExportList.size();
for (int i = 0; i < openFileList.size(); ++i) { for (int i = 0; i < openFileList.size(); ++i) {
QObject::connect(windowList[i], &DocumentWindow::workingStatusChanged, &app, checkToSafelyExit); QObject::connect(windowList[i], &DocumentWindow::workingStatusChanged, &app, checkToSafelyExit);
} }
for (int i = 0; i < openFileList.size(); ++i) { for (int i = 0; i < openFileList.size(); ++i) {
QObject::connect(windowList[i], &DocumentWindow::waitingExportFinished, &app, [&](const QString &filename, bool isSuccessful) { QObject::connect(windowList[i], &DocumentWindow::waitingExportFinished, &app, [&](const QString& filename, bool isSuccessful) {
qDebug() << "Export to" << filename << (isSuccessful ? "isSuccessful" : "failed"); qDebug() << "Export to" << filename << (isSuccessful ? "isSuccessful" : "failed");
++finishedExportFileNum; ++finishedExportFileNum;
if (isSuccessful) if (isSuccessful)
@ -112,6 +110,6 @@ int main(int argc, char *argv[])
windowList[i]->openPathAs(openFileList[i], openFileList[i]); windowList[i]->openPathAs(openFileList[i], openFileList[i]);
} }
} }
return app.exec(); return app.exec();
} }

View File

@ -1,21 +1,21 @@
#include "material.h" #include "material.h"
#include "image_forever.h" #include "image_forever.h"
void initializeMaterialTexturesFromSnapshot(const dust3d::Snapshot &snapshot, void initializeMaterialTexturesFromSnapshot(const dust3d::Snapshot& snapshot,
const dust3d::Uuid &materialId, const dust3d::Uuid& materialId,
MaterialTextures &materialTextures, MaterialTextures& materialTextures,
float &tileScale) float& tileScale)
{ {
auto materialIdString = materialId.toString(); auto materialIdString = materialId.toString();
for (const auto &materialItem: snapshot.materials) { for (const auto& materialItem : snapshot.materials) {
if (materialIdString != dust3d::String::valueOrEmpty(materialItem.first, "id")) if (materialIdString != dust3d::String::valueOrEmpty(materialItem.first, "id"))
continue; continue;
for (const auto &layer: materialItem.second) { for (const auto& layer : materialItem.second) {
//FIXME: Only support one layer currently //FIXME: Only support one layer currently
auto findTileScale = layer.first.find("tileScale"); auto findTileScale = layer.first.find("tileScale");
if (findTileScale != layer.first.end()) if (findTileScale != layer.first.end())
tileScale = dust3d::String::toFloat(findTileScale->second); tileScale = dust3d::String::toFloat(findTileScale->second);
for (const auto &mapItem: layer.second) { for (const auto& mapItem : layer.second) {
auto textureType = dust3d::TextureTypeFromString(dust3d::String::valueOrEmpty(mapItem, "for").c_str()); auto textureType = dust3d::TextureTypeFromString(dust3d::String::valueOrEmpty(mapItem, "for").c_str());
if (textureType != dust3d::TextureType::None) { if (textureType != dust3d::TextureType::None) {
int index = (int)textureType - 1; int index = (int)textureType - 1;

View File

@ -2,18 +2,17 @@
#define DUST3D_APPLICATION_MATERIAL_H_ #define DUST3D_APPLICATION_MATERIAL_H_
#include <QImage> #include <QImage>
#include <dust3d/base/uuid.h>
#include <dust3d/base/texture_type.h>
#include <dust3d/base/snapshot.h> #include <dust3d/base/snapshot.h>
#include <dust3d/base/texture_type.h>
#include <dust3d/base/uuid.h>
struct MaterialTextures struct MaterialTextures {
{ const QImage* textureImages[(int)dust3d::TextureType::Count - 1] = { nullptr };
const QImage *textureImages[(int)dust3d::TextureType::Count - 1] = {nullptr};
}; };
void initializeMaterialTexturesFromSnapshot(const dust3d::Snapshot &snapshot, void initializeMaterialTexturesFromSnapshot(const dust3d::Snapshot& snapshot,
const dust3d::Uuid &materialId, const dust3d::Uuid& materialId,
MaterialTextures &materialTextures, MaterialTextures& materialTextures,
float &tileScale); float& tileScale);
#endif #endif

View File

@ -1,49 +1,49 @@
#include <QVBoxLayout> #include "material_edit_widget.h"
#include <QHBoxLayout> #include "document.h"
#include <QGridLayout> #include "float_number_widget.h"
#include "horizontal_line_widget.h"
#include "image_forever.h"
#include "theme.h"
#include "version.h"
#include <QFileDialog>
#include <QFormLayout> #include <QFormLayout>
#include <QGridLayout> #include <QGridLayout>
#include <QMenu> #include <QHBoxLayout>
#include <QWidgetAction>
#include <QLineEdit>
#include <QMessageBox>
#include <QFileDialog>
#include <QLabel> #include <QLabel>
#include <QLineEdit>
#include <QMenu>
#include <QMessageBox>
#include <QThread> #include <QThread>
#include "theme.h" #include <QVBoxLayout>
#include "material_edit_widget.h" #include <QWidgetAction>
#include "float_number_widget.h"
#include "version.h"
#include "image_forever.h"
#include "document.h"
#include "horizontal_line_widget.h"
ImagePreviewWidget *MaterialEditWidget::createMapButton() ImagePreviewWidget* MaterialEditWidget::createMapButton()
{ {
ImagePreviewWidget *mapButton = new ImagePreviewWidget; ImagePreviewWidget* mapButton = new ImagePreviewWidget;
mapButton->setFixedSize(Theme::partPreviewImageSize * 2, Theme::partPreviewImageSize * 2); mapButton->setFixedSize(Theme::partPreviewImageSize * 2, Theme::partPreviewImageSize * 2);
updateMapButtonBackground(mapButton, nullptr); updateMapButtonBackground(mapButton, nullptr);
return mapButton; return mapButton;
} }
QImage *MaterialEditWidget::pickImage() QImage* MaterialEditWidget::pickImage()
{ {
QString fileName = QFileDialog::getOpenFileName(this, QString(), QString(), QString fileName = QFileDialog::getOpenFileName(this, QString(), QString(),
tr("Image Files (*.png *.jpg *.bmp)")).trimmed(); tr("Image Files (*.png *.jpg *.bmp)"))
.trimmed();
if (fileName.isEmpty()) if (fileName.isEmpty())
return nullptr; return nullptr;
QImage *image = new QImage(); QImage* image = new QImage();
if (!image->load(fileName)) if (!image->load(fileName))
return nullptr; return nullptr;
return image; return image;
} }
MaterialEditWidget::MaterialEditWidget(const Document *document, QWidget *parent) : MaterialEditWidget::MaterialEditWidget(const Document* document, QWidget* parent)
QDialog(parent), : QDialog(parent)
m_document(document) , m_document(document)
{ {
setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
m_layers.resize(1); m_layers.resize(1);
m_previewWidget = new ModelWidget(this); m_previewWidget = new ModelWidget(this);
@ -51,24 +51,24 @@ MaterialEditWidget::MaterialEditWidget(const Document *document, QWidget *parent
m_previewWidget->resize(512, 512); m_previewWidget->resize(512, 512);
m_previewWidget->move(-128, -128); m_previewWidget->move(-128, -128);
m_previewWidget->setNotGraphics(true); m_previewWidget->setNotGraphics(true);
QFont nameFont; QFont nameFont;
nameFont.setWeight(QFont::Light); nameFont.setWeight(QFont::Light);
nameFont.setBold(false); nameFont.setBold(false);
QGridLayout *mapLayout = new QGridLayout; QGridLayout* mapLayout = new QGridLayout;
int row = 0; int row = 0;
int col = 0; int col = 0;
for (int i = 1; i < (int)dust3d::TextureType::Count; i++) { for (int i = 1; i < (int)dust3d::TextureType::Count; i++) {
QVBoxLayout *textureManageLayout = new QVBoxLayout; QVBoxLayout* textureManageLayout = new QVBoxLayout;
MaterialMap item; MaterialMap item;
item.forWhat = (dust3d::TextureType)i; item.forWhat = (dust3d::TextureType)i;
m_layers[0].maps.push_back(item); m_layers[0].maps.push_back(item);
ImagePreviewWidget *imageButton = createMapButton(); ImagePreviewWidget* imageButton = createMapButton();
connect(imageButton, &ImagePreviewWidget::clicked, [=]() { connect(imageButton, &ImagePreviewWidget::clicked, [=]() {
QImage *image = pickImage(); QImage* image = pickImage();
if (nullptr == image) if (nullptr == image)
return; return;
m_layers[0].maps[(int)i - 1].imageId = ImageForever::add(image); m_layers[0].maps[(int)i - 1].imageId = ImageForever::add(image);
@ -76,41 +76,41 @@ MaterialEditWidget::MaterialEditWidget(const Document *document, QWidget *parent
delete image; delete image;
emit layersAdjusted(); emit layersAdjusted();
}); });
QLabel *nameLabel = new QLabel(tr(dust3d::TextureTypeToDispName(item.forWhat).c_str())); QLabel* nameLabel = new QLabel(tr(dust3d::TextureTypeToDispName(item.forWhat).c_str()));
nameLabel->setFont(nameFont); nameLabel->setFont(nameFont);
QPushButton *eraser = new QPushButton(QChar(fa::eraser)); QPushButton* eraser = new QPushButton(QChar(fa::eraser));
Theme::initAwesomeToolButton(eraser); Theme::initAwesomeToolButton(eraser);
connect(eraser, &QPushButton::clicked, [=]() { connect(eraser, &QPushButton::clicked, [=]() {
m_layers[0].maps[(int)i - 1].imageId = dust3d::Uuid(); m_layers[0].maps[(int)i - 1].imageId = dust3d::Uuid();
updateMapButtonBackground(imageButton, nullptr); updateMapButtonBackground(imageButton, nullptr);
emit layersAdjusted(); emit layersAdjusted();
}); });
QHBoxLayout *textureTitleLayout = new QHBoxLayout; QHBoxLayout* textureTitleLayout = new QHBoxLayout;
textureTitleLayout->addWidget(eraser); textureTitleLayout->addWidget(eraser);
textureTitleLayout->addWidget(nameLabel); textureTitleLayout->addWidget(nameLabel);
textureTitleLayout->addStretch(); textureTitleLayout->addStretch();
textureManageLayout->addWidget(imageButton); textureManageLayout->addWidget(imageButton);
textureManageLayout->addLayout(textureTitleLayout); textureManageLayout->addLayout(textureTitleLayout);
m_textureMapButtons[i - 1] = imageButton; m_textureMapButtons[i - 1] = imageButton;
mapLayout->addLayout(textureManageLayout, row, col++); mapLayout->addLayout(textureManageLayout, row, col++);
if (col == 2) { if (col == 2) {
col = 0; col = 0;
row++; row++;
} }
} }
QVBoxLayout *rightLayout = new QVBoxLayout; QVBoxLayout* rightLayout = new QVBoxLayout;
rightLayout->addStretch(); rightLayout->addStretch();
rightLayout->addLayout(mapLayout); rightLayout->addLayout(mapLayout);
rightLayout->addStretch(); rightLayout->addStretch();
QHBoxLayout *paramtersLayout = new QHBoxLayout; QHBoxLayout* paramtersLayout = new QHBoxLayout;
paramtersLayout->setContentsMargins(256, 0, 0, 0); paramtersLayout->setContentsMargins(256, 0, 0, 0);
paramtersLayout->addStretch(); paramtersLayout->addStretch();
paramtersLayout->addLayout(rightLayout); paramtersLayout->addLayout(rightLayout);
@ -120,41 +120,41 @@ MaterialEditWidget::MaterialEditWidget(const Document *document, QWidget *parent
m_unsaved = true; m_unsaved = true;
updateTitle(); updateTitle();
}); });
QPushButton *saveButton = new QPushButton(tr("Save")); QPushButton* saveButton = new QPushButton(tr("Save"));
connect(saveButton, &QPushButton::clicked, this, &MaterialEditWidget::save); connect(saveButton, &QPushButton::clicked, this, &MaterialEditWidget::save);
saveButton->setDefault(true); saveButton->setDefault(true);
FloatNumberWidget *tileScaleWidget = new FloatNumberWidget; FloatNumberWidget* tileScaleWidget = new FloatNumberWidget;
tileScaleWidget->setItemName(tr("Tile Scale")); tileScaleWidget->setItemName(tr("Tile Scale"));
tileScaleWidget->setRange(0.01, 1.0); tileScaleWidget->setRange(0.01, 1.0);
tileScaleWidget->setValue(m_layers[0].tileScale); tileScaleWidget->setValue(m_layers[0].tileScale);
m_tileScaleSlider = tileScaleWidget; m_tileScaleSlider = tileScaleWidget;
connect(tileScaleWidget, &FloatNumberWidget::valueChanged, [=](float value) { connect(tileScaleWidget, &FloatNumberWidget::valueChanged, [=](float value) {
m_layers[0].tileScale = value; m_layers[0].tileScale = value;
emit layersAdjusted(); emit layersAdjusted();
}); });
QPushButton *tileScaleEraser = new QPushButton(QChar(fa::eraser)); QPushButton* tileScaleEraser = new QPushButton(QChar(fa::eraser));
Theme::initAwesomeToolButton(tileScaleEraser); Theme::initAwesomeToolButton(tileScaleEraser);
connect(tileScaleEraser, &QPushButton::clicked, [=]() { connect(tileScaleEraser, &QPushButton::clicked, [=]() {
tileScaleWidget->setValue(1.0); tileScaleWidget->setValue(1.0);
}); });
QHBoxLayout *tileScaleLayout = new QHBoxLayout; QHBoxLayout* tileScaleLayout = new QHBoxLayout;
tileScaleLayout->addWidget(tileScaleEraser); tileScaleLayout->addWidget(tileScaleEraser);
tileScaleLayout->addWidget(tileScaleWidget); tileScaleLayout->addWidget(tileScaleWidget);
tileScaleLayout->addStretch(); tileScaleLayout->addStretch();
QHBoxLayout *baseInfoLayout = new QHBoxLayout; QHBoxLayout* baseInfoLayout = new QHBoxLayout;
baseInfoLayout->addWidget(new QLabel(tr("Name"))); baseInfoLayout->addWidget(new QLabel(tr("Name")));
baseInfoLayout->addWidget(m_nameEdit); baseInfoLayout->addWidget(m_nameEdit);
baseInfoLayout->addStretch(); baseInfoLayout->addStretch();
baseInfoLayout->addWidget(saveButton); baseInfoLayout->addWidget(saveButton);
QVBoxLayout *mainLayout = new QVBoxLayout; QVBoxLayout* mainLayout = new QVBoxLayout;
mainLayout->addLayout(paramtersLayout); mainLayout->addLayout(paramtersLayout);
mainLayout->addStretch(); mainLayout->addStretch();
mainLayout->addWidget(new HorizontalLineWidget()); mainLayout->addWidget(new HorizontalLineWidget());
@ -176,7 +176,7 @@ MaterialEditWidget::MaterialEditWidget(const Document *document, QWidget *parent
updateTitle(); updateTitle();
} }
void MaterialEditWidget::updateMapButtonBackground(ImagePreviewWidget *button, const QImage *image) void MaterialEditWidget::updateMapButtonBackground(ImagePreviewWidget* button, const QImage* image)
{ {
if (nullptr == image) if (nullptr == image)
button->updateImage(QImage()); button->updateImage(QImage());
@ -189,7 +189,7 @@ void MaterialEditWidget::reject()
close(); close();
} }
void MaterialEditWidget::closeEvent(QCloseEvent *event) void MaterialEditWidget::closeEvent(QCloseEvent* event)
{ {
if (m_unsaved && !m_closed) { if (m_unsaved && !m_closed) {
QMessageBox::StandardButton answer = QMessageBox::question(this, QMessageBox::StandardButton answer = QMessageBox::question(this,
@ -235,7 +235,7 @@ void MaterialEditWidget::updatePreview()
qDebug() << "Material preview generating.."; qDebug() << "Material preview generating..";
QThread *thread = new QThread; QThread* thread = new QThread;
m_materialPreviewsGenerator = new MaterialPreviewsGenerator(); m_materialPreviewsGenerator = new MaterialPreviewsGenerator();
m_materialPreviewsGenerator->addMaterial(dust3d::Uuid(), m_layers); m_materialPreviewsGenerator->addMaterial(dust3d::Uuid(), m_layers);
m_materialPreviewsGenerator->moveToThread(thread); m_materialPreviewsGenerator->moveToThread(thread);
@ -279,7 +279,7 @@ void MaterialEditWidget::updateTitle()
setWindowTitle(applicationTitle(tr("New") + (m_unsaved ? "*" : ""))); setWindowTitle(applicationTitle(tr("New") + (m_unsaved ? "*" : "")));
return; return;
} }
const Material *material = m_document->findMaterial(m_materialId); const Material* material = m_document->findMaterial(m_materialId);
if (nullptr == material) { if (nullptr == material) {
qDebug() << "Find material failed:" << m_materialId; qDebug() << "Find material failed:" << m_materialId;
return; return;
@ -299,9 +299,9 @@ void MaterialEditWidget::setEditMaterialLayers(std::vector<MaterialLayer> layers
m_layers[0].maps[i - 1].imageId = dust3d::Uuid(); m_layers[0].maps[i - 1].imageId = dust3d::Uuid();
} }
if (!layers.empty()) { if (!layers.empty()) {
for (const auto &layer: layers) { for (const auto& layer : layers) {
m_layers[0].tileScale = layer.tileScale; m_layers[0].tileScale = layer.tileScale;
for (const auto &mapItem: layer.maps) { for (const auto& mapItem : layer.maps) {
int index = (int)mapItem.forWhat - 1; int index = (int)mapItem.forWhat - 1;
if (index >= 0 && index < (int)dust3d::TextureType::Count - 1) { if (index >= 0 && index < (int)dust3d::TextureType::Count - 1) {
m_layers[0].maps[index].imageId = mapItem.imageId; m_layers[0].maps[index].imageId = mapItem.imageId;

View File

@ -1,26 +1,24 @@
#ifndef DUST3D_APPLICATION_MATERIAL_EDIT_WIDGET_H_ #ifndef DUST3D_APPLICATION_MATERIAL_EDIT_WIDGET_H_
#define DUST3D_APPLICATION_MATERIAL_EDIT_WIDGET_H_ #define DUST3D_APPLICATION_MATERIAL_EDIT_WIDGET_H_
#include <QDialog>
#include <map>
#include <QCloseEvent>
#include <QLineEdit>
#include "model_widget.h"
#include "material_previews_generator.h"
#include "image_preview_widget.h"
#include "float_number_widget.h" #include "float_number_widget.h"
#include "image_preview_widget.h"
#include "material_layer.h" #include "material_layer.h"
#include "material_previews_generator.h"
#include "model_widget.h"
#include <QCloseEvent>
#include <QDialog>
#include <QLineEdit>
#include <map>
class Document; class Document;
enum class PopupWidgetType enum class PopupWidgetType {
{
PitchYawRoll, PitchYawRoll,
Intersection Intersection
}; };
class MaterialEditWidget : public QDialog class MaterialEditWidget : public QDialog {
{
Q_OBJECT Q_OBJECT
signals: signals:
void addMaterial(dust3d::Uuid materialId, QString name, std::vector<MaterialLayer> layers); void addMaterial(dust3d::Uuid materialId, QString name, std::vector<MaterialLayer> layers);
@ -28,8 +26,9 @@ signals:
void setMaterialLayers(dust3d::Uuid materialId, std::vector<MaterialLayer> layers); void setMaterialLayers(dust3d::Uuid materialId, std::vector<MaterialLayer> layers);
void renameMaterial(dust3d::Uuid materialId, QString name); void renameMaterial(dust3d::Uuid materialId, QString name);
void layersAdjusted(); void layersAdjusted();
public: public:
MaterialEditWidget(const Document *document, QWidget *parent=nullptr); MaterialEditWidget(const Document* document, QWidget* parent = nullptr);
~MaterialEditWidget(); ~MaterialEditWidget();
public slots: public slots:
void updatePreview(); void updatePreview();
@ -40,25 +39,27 @@ public slots:
void save(); void save();
void clearUnsaveState(); void clearUnsaveState();
void previewReady(); void previewReady();
protected: protected:
QSize sizeHint() const override; QSize sizeHint() const override;
void closeEvent(QCloseEvent *event) override; void closeEvent(QCloseEvent* event) override;
void reject() override; void reject() override;
private: private:
void updateMapButtonBackground(ImagePreviewWidget *button, const QImage *image); void updateMapButtonBackground(ImagePreviewWidget* button, const QImage* image);
ImagePreviewWidget *createMapButton(); ImagePreviewWidget* createMapButton();
QImage *pickImage(); QImage* pickImage();
const Document *m_document = nullptr; const Document* m_document = nullptr;
MaterialPreviewsGenerator *m_materialPreviewsGenerator = nullptr; MaterialPreviewsGenerator* m_materialPreviewsGenerator = nullptr;
ModelWidget *m_previewWidget = nullptr; ModelWidget* m_previewWidget = nullptr;
FloatNumberWidget *m_tileScaleSlider = nullptr; FloatNumberWidget* m_tileScaleSlider = nullptr;
bool m_isPreviewDirty = false; bool m_isPreviewDirty = false;
bool m_closed = false; bool m_closed = false;
dust3d::Uuid m_materialId; dust3d::Uuid m_materialId;
bool m_unsaved = false; bool m_unsaved = false;
QLineEdit *m_nameEdit = nullptr; QLineEdit* m_nameEdit = nullptr;
std::vector<MaterialLayer> m_layers; std::vector<MaterialLayer> m_layers;
ImagePreviewWidget *m_textureMapButtons[(int)dust3d::TextureType::Count - 1] = {nullptr}; ImagePreviewWidget* m_textureMapButtons[(int)dust3d::TextureType::Count - 1] = { nullptr };
}; };
#endif #endif

View File

@ -1,19 +1,17 @@
#ifndef DUST3D_APPLICATION_MATERIAL_LAYER_H_ #ifndef DUST3D_APPLICATION_MATERIAL_LAYER_H_
#define DUST3D_APPLICATION_MATERIAL_LAYER_H_ #define DUST3D_APPLICATION_MATERIAL_LAYER_H_
#include <vector>
#include <dust3d/base/texture_type.h> #include <dust3d/base/texture_type.h>
#include <dust3d/base/uuid.h> #include <dust3d/base/uuid.h>
#include <vector>
class MaterialMap class MaterialMap {
{
public: public:
dust3d::TextureType forWhat; dust3d::TextureType forWhat;
dust3d::Uuid imageId; dust3d::Uuid imageId;
}; };
class MaterialLayer class MaterialLayer {
{
public: public:
std::vector<MaterialMap> maps; std::vector<MaterialMap> maps;
float tileScale = 1.0; float tileScale = 1.0;

View File

@ -1,15 +1,15 @@
#include "material_list_widget.h"
#include "document.h"
#include <QApplication>
#include <QClipboard>
#include <QGuiApplication> #include <QGuiApplication>
#include <QMenu> #include <QMenu>
#include <QXmlStreamWriter> #include <QXmlStreamWriter>
#include <QClipboard>
#include <QApplication>
#include <dust3d/base/snapshot_xml.h> #include <dust3d/base/snapshot_xml.h>
#include "material_list_widget.h"
#include "document.h"
MaterialListWidget::MaterialListWidget(const Document *document, QWidget *parent) : MaterialListWidget::MaterialListWidget(const Document* document, QWidget* parent)
QTreeWidget(parent), : QTreeWidget(parent)
m_document(document) , m_document(document)
{ {
setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
setFocusPolicy(Qt::NoFocus); setFocusPolicy(Qt::NoFocus);
@ -59,7 +59,7 @@ void MaterialListWidget::updateMaterialSelectState(dust3d::Uuid materialId, bool
qDebug() << "Find material item failed:" << materialId; qDebug() << "Find material item failed:" << materialId;
return; return;
} }
MaterialWidget *materialWidget = (MaterialWidget *)itemWidget(findItemResult->second.first, findItemResult->second.second); MaterialWidget* materialWidget = (MaterialWidget*)itemWidget(findItemResult->second.first, findItemResult->second.second);
materialWidget->updateCheckedState(selected); materialWidget->updateCheckedState(selected);
} }
@ -90,7 +90,7 @@ void MaterialListWidget::selectMaterial(dust3d::Uuid materialId, bool multiple)
} }
} }
if (!m_selectedMaterialIds.empty()) { if (!m_selectedMaterialIds.empty()) {
for (const auto &id: m_selectedMaterialIds) { for (const auto& id : m_selectedMaterialIds) {
updateMaterialSelectState(id, false); updateMaterialSelectState(id, false);
} }
m_selectedMaterialIds.clear(); m_selectedMaterialIds.clear();
@ -107,20 +107,20 @@ void MaterialListWidget::selectMaterial(dust3d::Uuid materialId, bool multiple)
} }
} }
void MaterialListWidget::mousePressEvent(QMouseEvent *event) void MaterialListWidget::mousePressEvent(QMouseEvent* event)
{ {
QModelIndex itemIndex = indexAt(event->pos()); QModelIndex itemIndex = indexAt(event->pos());
QTreeView::mousePressEvent(event); QTreeView::mousePressEvent(event);
if (event->button() == Qt::LeftButton) { if (event->button() == Qt::LeftButton) {
bool multiple = QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ControlModifier); bool multiple = QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ControlModifier);
if (itemIndex.isValid()) { if (itemIndex.isValid()) {
QTreeWidgetItem *item = itemFromIndex(itemIndex); QTreeWidgetItem* item = itemFromIndex(itemIndex);
auto materialId = dust3d::Uuid(item->data(itemIndex.column(), Qt::UserRole).toString().toUtf8().constData()); auto materialId = dust3d::Uuid(item->data(itemIndex.column(), Qt::UserRole).toString().toUtf8().constData());
if (QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ShiftModifier)) { if (QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ShiftModifier)) {
bool startAdd = false; bool startAdd = false;
bool stopAdd = false; bool stopAdd = false;
std::vector<dust3d::Uuid> waitQueue; std::vector<dust3d::Uuid> waitQueue;
for (const auto &childId: m_document->materialIdList) { for (const auto& childId : m_document->materialIdList) {
if (m_shiftStartMaterialId == childId || materialId == childId) { if (m_shiftStartMaterialId == childId || materialId == childId) {
if (startAdd) { if (startAdd) {
stopAdd = true; stopAdd = true;
@ -135,7 +135,7 @@ void MaterialListWidget::mousePressEvent(QMouseEvent *event)
} }
if (stopAdd && !waitQueue.empty()) { if (stopAdd && !waitQueue.empty()) {
if (!m_selectedMaterialIds.empty()) { if (!m_selectedMaterialIds.empty()) {
for (const auto &id: m_selectedMaterialIds) { for (const auto& id : m_selectedMaterialIds) {
updateMaterialSelectState(id, false); updateMaterialSelectState(id, false);
} }
m_selectedMaterialIds.clear(); m_selectedMaterialIds.clear();
@ -143,7 +143,7 @@ void MaterialListWidget::mousePressEvent(QMouseEvent *event)
if (!m_currentSelectedMaterialId.isNull()) { if (!m_currentSelectedMaterialId.isNull()) {
m_currentSelectedMaterialId = dust3d::Uuid(); m_currentSelectedMaterialId = dust3d::Uuid();
} }
for (const auto &waitId: waitQueue) { for (const auto& waitId : waitQueue) {
selectMaterial(waitId, true); selectMaterial(waitId, true);
} }
} }
@ -161,11 +161,10 @@ void MaterialListWidget::mousePressEvent(QMouseEvent *event)
bool MaterialListWidget::isMaterialSelected(dust3d::Uuid materialId) bool MaterialListWidget::isMaterialSelected(dust3d::Uuid materialId)
{ {
return (m_currentSelectedMaterialId == materialId || return (m_currentSelectedMaterialId == materialId || m_selectedMaterialIds.find(materialId) != m_selectedMaterialIds.end());
m_selectedMaterialIds.find(materialId) != m_selectedMaterialIds.end());
} }
void MaterialListWidget::showContextMenu(const QPoint &pos) void MaterialListWidget::showContextMenu(const QPoint& pos)
{ {
if (!m_hasContextMenu) if (!m_hasContextMenu)
return; return;
@ -177,7 +176,7 @@ void MaterialListWidget::showContextMenu(const QPoint &pos)
unorderedMaterialIds.insert(m_currentSelectedMaterialId); unorderedMaterialIds.insert(m_currentSelectedMaterialId);
std::vector<dust3d::Uuid> materialIds; std::vector<dust3d::Uuid> materialIds;
for (const auto &cand: m_document->materialIdList) { for (const auto& cand : m_document->materialIdList) {
if (unorderedMaterialIds.find(cand) != unorderedMaterialIds.end()) if (unorderedMaterialIds.find(cand) != unorderedMaterialIds.end())
materialIds.push_back(cand); materialIds.push_back(cand);
} }
@ -205,7 +204,7 @@ void MaterialListWidget::showContextMenu(const QPoint &pos)
QAction deleteAction(tr("Delete"), this); QAction deleteAction(tr("Delete"), this);
if (!materialIds.empty()) { if (!materialIds.empty()) {
connect(&deleteAction, &QAction::triggered, [=]() { connect(&deleteAction, &QAction::triggered, [=]() {
for (const auto &materialId: materialIds) for (const auto& materialId : materialIds)
emit removeMaterial(materialId); emit removeMaterial(materialId);
}); });
contextMenu.addAction(&deleteAction); contextMenu.addAction(&deleteAction);
@ -214,7 +213,7 @@ void MaterialListWidget::showContextMenu(const QPoint &pos)
contextMenu.exec(mapToGlobal(pos)); contextMenu.exec(mapToGlobal(pos));
} }
void MaterialListWidget::resizeEvent(QResizeEvent *event) void MaterialListWidget::resizeEvent(QResizeEvent* event)
{ {
QTreeWidget::resizeEvent(event); QTreeWidget::resizeEvent(event);
if (calculateColumnCount() != columnCount()) if (calculateColumnCount() != columnCount())
@ -247,11 +246,11 @@ void MaterialListWidget::reload()
setColumnCount(columns); setColumnCount(columns);
for (int i = 0; i < columns; i++) for (int i = 0; i < columns; i++)
setColumnWidth(i, columnWidth); setColumnWidth(i, columnWidth);
std::vector<dust3d::Uuid> orderedMaterialIdList = m_document->materialIdList; std::vector<dust3d::Uuid> orderedMaterialIdList = m_document->materialIdList;
std::sort(orderedMaterialIdList.begin(), orderedMaterialIdList.end(), [&](const dust3d::Uuid &firstMaterialId, const dust3d::Uuid &secondMaterialId) { std::sort(orderedMaterialIdList.begin(), orderedMaterialIdList.end(), [&](const dust3d::Uuid& firstMaterialId, const dust3d::Uuid& secondMaterialId) {
const auto *firstMaterial = m_document->findMaterial(firstMaterialId); const auto* firstMaterial = m_document->findMaterial(firstMaterialId);
const auto *secondMaterial = m_document->findMaterial(secondMaterialId); const auto* secondMaterial = m_document->findMaterial(secondMaterialId);
if (nullptr == firstMaterial || nullptr == secondMaterial) if (nullptr == firstMaterial || nullptr == secondMaterial)
return false; return false;
return QString::compare(firstMaterial->name, secondMaterial->name, Qt::CaseInsensitive) < 0; return QString::compare(firstMaterial->name, secondMaterial->name, Qt::CaseInsensitive) < 0;
@ -259,13 +258,13 @@ void MaterialListWidget::reload()
decltype(orderedMaterialIdList.size()) materialIndex = 0; decltype(orderedMaterialIdList.size()) materialIndex = 0;
while (materialIndex < orderedMaterialIdList.size()) { while (materialIndex < orderedMaterialIdList.size()) {
QTreeWidgetItem *item = new QTreeWidgetItem(this); QTreeWidgetItem* item = new QTreeWidgetItem(this);
item->setFlags((item->flags() | Qt::ItemIsEnabled) & ~(Qt::ItemIsSelectable) & ~(Qt::ItemIsEditable)); item->setFlags((item->flags() | Qt::ItemIsEnabled) & ~(Qt::ItemIsSelectable) & ~(Qt::ItemIsEditable));
for (int col = 0; col < columns && materialIndex < orderedMaterialIdList.size(); col++, materialIndex++) { for (int col = 0; col < columns && materialIndex < orderedMaterialIdList.size(); col++, materialIndex++) {
const auto &materialId = orderedMaterialIdList[materialIndex]; const auto& materialId = orderedMaterialIdList[materialIndex];
item->setSizeHint(col, QSize(columnWidth, MaterialWidget::preferredHeight() + 2)); item->setSizeHint(col, QSize(columnWidth, MaterialWidget::preferredHeight() + 2));
item->setData(col, Qt::UserRole, QString(materialId.toString().c_str())); item->setData(col, Qt::UserRole, QString(materialId.toString().c_str()));
MaterialWidget *widget = new MaterialWidget(m_document, materialId); MaterialWidget* widget = new MaterialWidget(m_document, materialId);
connect(widget, &MaterialWidget::modifyMaterial, this, &MaterialListWidget::modifyMaterial); connect(widget, &MaterialWidget::modifyMaterial, this, &MaterialListWidget::modifyMaterial);
setItemWidget(item, col, widget); setItemWidget(item, col, widget);
widget->reload(); widget->reload();
@ -301,9 +300,9 @@ void MaterialListWidget::copy()
dust3d::Snapshot snapshot; dust3d::Snapshot snapshot;
m_document->toSnapshot(&snapshot, emptySet, DocumentToSnapshotFor::Materials, m_document->toSnapshot(&snapshot, emptySet, DocumentToSnapshotFor::Materials,
limitMaterialIds); limitMaterialIds);
std::string snapshotXml; std::string snapshotXml;
dust3d::saveSnapshotToXmlString(snapshot, snapshotXml); dust3d::saveSnapshotToXmlString(snapshot, snapshotXml);
QClipboard *clipboard = QApplication::clipboard(); QClipboard* clipboard = QApplication::clipboard();
clipboard->setText(snapshotXml.c_str()); clipboard->setText(snapshotXml.c_str());
} }

View File

@ -1,41 +1,43 @@
#ifndef DUST3D_APPLICATION_MATERIAL_LIST_WIDGET_H_ #ifndef DUST3D_APPLICATION_MATERIAL_LIST_WIDGET_H_
#define DUST3D_APPLICATION_MATERIAL_LIST_WIDGET_H_ #define DUST3D_APPLICATION_MATERIAL_LIST_WIDGET_H_
#include "material_widget.h"
#include <QMouseEvent>
#include <QTreeWidget> #include <QTreeWidget>
#include <map> #include <map>
#include <QMouseEvent>
#include "material_widget.h"
class Document; class Document;
class MaterialListWidget : public QTreeWidget class MaterialListWidget : public QTreeWidget {
{
Q_OBJECT Q_OBJECT
signals: signals:
void removeMaterial(dust3d::Uuid materialId); void removeMaterial(dust3d::Uuid materialId);
void modifyMaterial(dust3d::Uuid materialId); void modifyMaterial(dust3d::Uuid materialId);
void cornerButtonClicked(dust3d::Uuid materialId); void cornerButtonClicked(dust3d::Uuid materialId);
void currentSelectedMaterialChanged(dust3d::Uuid materialId); void currentSelectedMaterialChanged(dust3d::Uuid materialId);
public: public:
MaterialListWidget(const Document *document, QWidget *parent=nullptr); MaterialListWidget(const Document* document, QWidget* parent = nullptr);
bool isMaterialSelected(dust3d::Uuid materialId); bool isMaterialSelected(dust3d::Uuid materialId);
void enableMultipleSelection(bool enabled); void enableMultipleSelection(bool enabled);
public slots: public slots:
void reload(); void reload();
void removeAllContent(); void removeAllContent();
void materialRemoved(dust3d::Uuid materialId); void materialRemoved(dust3d::Uuid materialId);
void showContextMenu(const QPoint &pos); void showContextMenu(const QPoint& pos);
void selectMaterial(dust3d::Uuid materialId, bool multiple=false); void selectMaterial(dust3d::Uuid materialId, bool multiple = false);
void copy(); void copy();
void setHasContextMenu(bool hasContextMenu); void setHasContextMenu(bool hasContextMenu);
protected: protected:
void resizeEvent(QResizeEvent *event) override; void resizeEvent(QResizeEvent* event) override;
void mousePressEvent(QMouseEvent *event) override; void mousePressEvent(QMouseEvent* event) override;
private: private:
int calculateColumnCount(); int calculateColumnCount();
void updateMaterialSelectState(dust3d::Uuid materialId, bool selected); void updateMaterialSelectState(dust3d::Uuid materialId, bool selected);
const Document *m_document = nullptr; const Document* m_document = nullptr;
std::map<dust3d::Uuid, std::pair<QTreeWidgetItem *, int>> m_itemMap; std::map<dust3d::Uuid, std::pair<QTreeWidgetItem*, int>> m_itemMap;
std::set<dust3d::Uuid> m_selectedMaterialIds; std::set<dust3d::Uuid> m_selectedMaterialIds;
dust3d::Uuid m_currentSelectedMaterialId; dust3d::Uuid m_currentSelectedMaterialId;
dust3d::Uuid m_shiftStartMaterialId; dust3d::Uuid m_shiftStartMaterialId;

View File

@ -1,34 +1,34 @@
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QPushButton>
#include "material_manage_widget.h" #include "material_manage_widget.h"
#include "theme.h"
#include "material_edit_widget.h"
#include "info_label.h"
#include "document.h" #include "document.h"
#include "info_label.h"
#include "material_edit_widget.h"
#include "theme.h"
#include <QHBoxLayout>
#include <QPushButton>
#include <QVBoxLayout>
MaterialManageWidget::MaterialManageWidget(const Document *document, QWidget *parent) : MaterialManageWidget::MaterialManageWidget(const Document* document, QWidget* parent)
QWidget(parent), : QWidget(parent)
m_document(document) , m_document(document)
{ {
QPushButton *addMaterialButton = new QPushButton(Theme::awesome()->icon(fa::plus), tr("Add Material...")); QPushButton* addMaterialButton = new QPushButton(Theme::awesome()->icon(fa::plus), tr("Add Material..."));
connect(addMaterialButton, &QPushButton::clicked, this, &MaterialManageWidget::showAddMaterialDialog); connect(addMaterialButton, &QPushButton::clicked, this, &MaterialManageWidget::showAddMaterialDialog);
QHBoxLayout *toolsLayout = new QHBoxLayout; QHBoxLayout* toolsLayout = new QHBoxLayout;
toolsLayout->addWidget(addMaterialButton); toolsLayout->addWidget(addMaterialButton);
m_materialListWidget = new MaterialListWidget(document); m_materialListWidget = new MaterialListWidget(document);
connect(m_materialListWidget, &MaterialListWidget::modifyMaterial, this, &MaterialManageWidget::showMaterialDialog); connect(m_materialListWidget, &MaterialListWidget::modifyMaterial, this, &MaterialManageWidget::showMaterialDialog);
QVBoxLayout *mainLayout = new QVBoxLayout; QVBoxLayout* mainLayout = new QVBoxLayout;
mainLayout->addLayout(toolsLayout); mainLayout->addLayout(toolsLayout);
mainLayout->addWidget(m_materialListWidget); mainLayout->addWidget(m_materialListWidget);
setLayout(mainLayout); setLayout(mainLayout);
} }
MaterialListWidget *MaterialManageWidget::materialListWidget() MaterialListWidget* MaterialManageWidget::materialListWidget()
{ {
return m_materialListWidget; return m_materialListWidget;
} }
@ -45,10 +45,10 @@ void MaterialManageWidget::showAddMaterialDialog()
void MaterialManageWidget::showMaterialDialog(dust3d::Uuid materialId) void MaterialManageWidget::showMaterialDialog(dust3d::Uuid materialId)
{ {
MaterialEditWidget *materialEditWidget = new MaterialEditWidget(m_document); MaterialEditWidget* materialEditWidget = new MaterialEditWidget(m_document);
materialEditWidget->setAttribute(Qt::WA_DeleteOnClose); materialEditWidget->setAttribute(Qt::WA_DeleteOnClose);
if (!materialId.isNull()) { if (!materialId.isNull()) {
const Material *material = m_document->findMaterial(materialId); const Material* material = m_document->findMaterial(materialId);
if (nullptr != material) { if (nullptr != material) {
materialEditWidget->setEditMaterialId(materialId); materialEditWidget->setEditMaterialId(materialId);
materialEditWidget->setEditMaterialName(material->name); materialEditWidget->setEditMaterialName(material->name);
@ -58,7 +58,7 @@ void MaterialManageWidget::showMaterialDialog(dust3d::Uuid materialId)
} }
materialEditWidget->show(); materialEditWidget->show();
connect(materialEditWidget, &QDialog::destroyed, [=]() { connect(materialEditWidget, &QDialog::destroyed, [=]() {
emit unregisterDialog((QWidget *)materialEditWidget); emit unregisterDialog((QWidget*)materialEditWidget);
}); });
emit registerDialog((QWidget *)materialEditWidget); emit registerDialog((QWidget*)materialEditWidget);
} }

View File

@ -1,28 +1,30 @@
#ifndef DUST3D_APPLICATION_MATERIAL_MANAGE_WIDGET_H_ #ifndef DUST3D_APPLICATION_MATERIAL_MANAGE_WIDGET_H_
#define DUST3D_APPLICATION_MATERIAL_MANAGE_WIDGET_H_ #define DUST3D_APPLICATION_MATERIAL_MANAGE_WIDGET_H_
#include <QWidget>
#include "material_list_widget.h" #include "material_list_widget.h"
#include <QWidget>
class Document; class Document;
class MaterialManageWidget : public QWidget class MaterialManageWidget : public QWidget {
{
Q_OBJECT Q_OBJECT
signals: signals:
void registerDialog(QWidget *widget); void registerDialog(QWidget* widget);
void unregisterDialog(QWidget *widget); void unregisterDialog(QWidget* widget);
public: public:
MaterialManageWidget(const Document *document, QWidget *parent=nullptr); MaterialManageWidget(const Document* document, QWidget* parent = nullptr);
MaterialListWidget *materialListWidget(); MaterialListWidget* materialListWidget();
protected: protected:
virtual QSize sizeHint() const; virtual QSize sizeHint() const;
public slots: public slots:
void showAddMaterialDialog(); void showAddMaterialDialog();
void showMaterialDialog(dust3d::Uuid materialId); void showMaterialDialog(dust3d::Uuid materialId);
private: private:
const Document *m_document = nullptr; const Document* m_document = nullptr;
MaterialListWidget *m_materialListWidget = nullptr; MaterialListWidget* m_materialListWidget = nullptr;
}; };
#endif #endif

View File

@ -1,14 +1,14 @@
#include <QGuiApplication> #include "material_previews_generator.h"
#include <QElapsedTimer> #include "image_forever.h"
#include "mesh_generator.h"
#include "mesh_result_post_processor.h"
#include "texture_generator.h"
#include <QDebug> #include <QDebug>
#include <QElapsedTimer>
#include <QFile> #include <QFile>
#include <QGuiApplication>
#include <dust3d/base/ds3_file.h> #include <dust3d/base/ds3_file.h>
#include <dust3d/base/snapshot_xml.h> #include <dust3d/base/snapshot_xml.h>
#include "material_previews_generator.h"
#include "mesh_generator.h"
#include "texture_generator.h"
#include "image_forever.h"
#include "mesh_result_post_processor.h"
MaterialPreviewsGenerator::MaterialPreviewsGenerator() MaterialPreviewsGenerator::MaterialPreviewsGenerator()
{ {
@ -16,78 +16,78 @@ MaterialPreviewsGenerator::MaterialPreviewsGenerator()
MaterialPreviewsGenerator::~MaterialPreviewsGenerator() MaterialPreviewsGenerator::~MaterialPreviewsGenerator()
{ {
for (auto &item: m_previews) { for (auto& item : m_previews) {
delete item.second; delete item.second;
} }
} }
void MaterialPreviewsGenerator::addMaterial(dust3d::Uuid materialId, const std::vector<MaterialLayer> &layers) void MaterialPreviewsGenerator::addMaterial(dust3d::Uuid materialId, const std::vector<MaterialLayer>& layers)
{ {
m_materials.push_back({materialId, layers}); m_materials.push_back({ materialId, layers });
} }
const std::set<dust3d::Uuid> &MaterialPreviewsGenerator::generatedPreviewMaterialIds() const std::set<dust3d::Uuid>& MaterialPreviewsGenerator::generatedPreviewMaterialIds()
{ {
return m_generatedMaterialIds; return m_generatedMaterialIds;
} }
ModelMesh *MaterialPreviewsGenerator::takePreview(dust3d::Uuid materialId) ModelMesh* MaterialPreviewsGenerator::takePreview(dust3d::Uuid materialId)
{ {
ModelMesh *resultMesh = m_previews[materialId]; ModelMesh* resultMesh = m_previews[materialId];
m_previews[materialId] = nullptr; m_previews[materialId] = nullptr;
return resultMesh; return resultMesh;
} }
void MaterialPreviewsGenerator::generate() void MaterialPreviewsGenerator::generate()
{ {
dust3d::Snapshot *snapshot = new dust3d::Snapshot; dust3d::Snapshot* snapshot = new dust3d::Snapshot;
QFile file(":/resources/material-demo-model.ds3"); QFile file(":/resources/material-demo-model.ds3");
file.open(QFile::ReadOnly); file.open(QFile::ReadOnly);
QByteArray fileData = file.readAll(); QByteArray fileData = file.readAll();
std::vector<dust3d::Uuid> partIds; std::vector<dust3d::Uuid> partIds;
dust3d::Ds3FileReader ds3Reader((const std::uint8_t *)fileData.data(), fileData.size()); dust3d::Ds3FileReader ds3Reader((const std::uint8_t*)fileData.data(), fileData.size());
for (int i = 0; i < (int)ds3Reader.items().size(); ++i) { for (int i = 0; i < (int)ds3Reader.items().size(); ++i) {
dust3d::Ds3ReaderItem item = ds3Reader.items().at(i); dust3d::Ds3ReaderItem item = ds3Reader.items().at(i);
if (item.type == "model") { if (item.type == "model") {
std::vector<std::uint8_t> data; std::vector<std::uint8_t> data;
ds3Reader.loadItem(item.name, &data); ds3Reader.loadItem(item.name, &data);
std::string xmlString((char *)data.data(), data.size()); std::string xmlString((char*)data.data(), data.size());
dust3d::loadSnapshotFromXmlString(snapshot, (char *)xmlString.c_str()); dust3d::loadSnapshotFromXmlString(snapshot, (char*)xmlString.c_str());
for (const auto &item: snapshot->parts) { for (const auto& item : snapshot->parts) {
partIds.push_back(dust3d::Uuid(item.first)); partIds.push_back(dust3d::Uuid(item.first));
} }
} }
} }
dust3d::MeshGenerator::GeneratedCacheContext *cacheContext = new dust3d::MeshGenerator::GeneratedCacheContext(); dust3d::MeshGenerator::GeneratedCacheContext* cacheContext = new dust3d::MeshGenerator::GeneratedCacheContext();
MeshGenerator *meshGenerator = new MeshGenerator(snapshot); MeshGenerator* meshGenerator = new MeshGenerator(snapshot);
meshGenerator->setGeneratedCacheContext(cacheContext); meshGenerator->setGeneratedCacheContext(cacheContext);
meshGenerator->generate(); meshGenerator->generate();
for (const auto &mirror: cacheContext->partMirrorIdMap) { for (const auto& mirror : cacheContext->partMirrorIdMap) {
partIds.push_back(dust3d::Uuid(mirror.first)); partIds.push_back(dust3d::Uuid(mirror.first));
} }
dust3d::Object *object = meshGenerator->takeObject(); dust3d::Object* object = meshGenerator->takeObject();
if (nullptr != object) { if (nullptr != object) {
MeshResultPostProcessor *poseProcessor = new MeshResultPostProcessor(*object); MeshResultPostProcessor* poseProcessor = new MeshResultPostProcessor(*object);
poseProcessor->poseProcess(); poseProcessor->poseProcess();
delete object; delete object;
object = poseProcessor->takePostProcessedObject(); object = poseProcessor->takePostProcessedObject();
delete poseProcessor; delete poseProcessor;
} }
if (nullptr != object) { if (nullptr != object) {
for (const auto &material: m_materials) { for (const auto& material : m_materials) {
TextureGenerator *textureGenerator = new TextureGenerator(*object); TextureGenerator* textureGenerator = new TextureGenerator(*object);
for (const auto &layer: material.second) { for (const auto& layer : material.second) {
for (const auto &mapItem: layer.maps) { for (const auto& mapItem : layer.maps) {
const QImage *image = ImageForever::get(mapItem.imageId); const QImage* image = ImageForever::get(mapItem.imageId);
if (nullptr == image) if (nullptr == image)
continue; continue;
for (const auto &partId: partIds) { for (const auto& partId : partIds) {
if (dust3d::TextureType::BaseColor == mapItem.forWhat) if (dust3d::TextureType::BaseColor == mapItem.forWhat)
textureGenerator->addPartColorMap(partId, image, layer.tileScale); textureGenerator->addPartColorMap(partId, image, layer.tileScale);
else if (dust3d::TextureType::Normal == mapItem.forWhat) else if (dust3d::TextureType::Normal == mapItem.forWhat)
@ -102,7 +102,7 @@ void MaterialPreviewsGenerator::generate()
} }
} }
textureGenerator->generate(); textureGenerator->generate();
ModelMesh *texturedResultMesh = textureGenerator->takeResultMesh(); ModelMesh* texturedResultMesh = textureGenerator->takeResultMesh();
if (nullptr != texturedResultMesh) { if (nullptr != texturedResultMesh) {
m_previews[material.first] = new ModelMesh(*texturedResultMesh); m_previews[material.first] = new ModelMesh(*texturedResultMesh);
m_generatedMaterialIds.insert(material.first); m_generatedMaterialIds.insert(material.first);
@ -111,9 +111,9 @@ void MaterialPreviewsGenerator::generate()
delete textureGenerator; delete textureGenerator;
} }
} }
delete object; delete object;
delete meshGenerator; delete meshGenerator;
delete cacheContext; delete cacheContext;
} }

View File

@ -1,29 +1,29 @@
#ifndef DUST3D_APPLICATION_MATERIAL_PREVIEWS_GENERATOR_H_ #ifndef DUST3D_APPLICATION_MATERIAL_PREVIEWS_GENERATOR_H_
#define DUST3D_APPLICATION_MATERIAL_PREVIEWS_GENERATOR_H_ #define DUST3D_APPLICATION_MATERIAL_PREVIEWS_GENERATOR_H_
#include "material_layer.h"
#include "model_mesh.h"
#include <QObject> #include <QObject>
#include <map> #include <map>
#include <vector> #include <vector>
#include "model_mesh.h"
#include "material_layer.h"
class MaterialPreviewsGenerator : public QObject class MaterialPreviewsGenerator : public QObject {
{
Q_OBJECT Q_OBJECT
public: public:
MaterialPreviewsGenerator(); MaterialPreviewsGenerator();
~MaterialPreviewsGenerator(); ~MaterialPreviewsGenerator();
void addMaterial(dust3d::Uuid materialId, const std::vector<MaterialLayer> &layers); void addMaterial(dust3d::Uuid materialId, const std::vector<MaterialLayer>& layers);
const std::set<dust3d::Uuid> &generatedPreviewMaterialIds(); const std::set<dust3d::Uuid>& generatedPreviewMaterialIds();
ModelMesh *takePreview(dust3d::Uuid materialId); ModelMesh* takePreview(dust3d::Uuid materialId);
void generate(); void generate();
signals: signals:
void finished(); void finished();
public slots: public slots:
void process(); void process();
private: private:
std::vector<std::pair<dust3d::Uuid, std::vector<MaterialLayer>>> m_materials; std::vector<std::pair<dust3d::Uuid, std::vector<MaterialLayer>>> m_materials;
std::map<dust3d::Uuid, ModelMesh *> m_previews; std::map<dust3d::Uuid, ModelMesh*> m_previews;
std::set<dust3d::Uuid> m_generatedMaterialIds; std::set<dust3d::Uuid> m_generatedMaterialIds;
}; };

View File

@ -1,10 +1,10 @@
#include <QVBoxLayout>
#include "material_widget.h" #include "material_widget.h"
#include "document.h" #include "document.h"
#include <QVBoxLayout>
MaterialWidget::MaterialWidget(const Document *document, dust3d::Uuid materialId) : MaterialWidget::MaterialWidget(const Document* document, dust3d::Uuid materialId)
m_materialId(materialId), : m_materialId(materialId)
m_document(document) , m_document(document)
{ {
setObjectName("MaterialFrame"); setObjectName("MaterialFrame");
@ -23,7 +23,7 @@ MaterialWidget::MaterialWidget(const Document *document, dust3d::Uuid materialId
nameFont.setBold(false); nameFont.setBold(false);
m_nameLabel->setFont(nameFont); m_nameLabel->setFont(nameFont);
QVBoxLayout *mainLayout = new QVBoxLayout; QVBoxLayout* mainLayout = new QVBoxLayout;
mainLayout->setContentsMargins(0, 0, 0, 0); mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->addStretch(); mainLayout->addStretch();
mainLayout->addWidget(m_nameLabel); mainLayout->addWidget(m_nameLabel);
@ -36,7 +36,7 @@ MaterialWidget::MaterialWidget(const Document *document, dust3d::Uuid materialId
connect(document, &Document::materialPreviewChanged, this, &MaterialWidget::updatePreview); connect(document, &Document::materialPreviewChanged, this, &MaterialWidget::updatePreview);
} }
void MaterialWidget::resizeEvent(QResizeEvent *event) void MaterialWidget::resizeEvent(QResizeEvent* event)
{ {
QWidget::resizeEvent(event); QWidget::resizeEvent(event);
m_previewWidget->move((width() - Theme::materialPreviewImageSize) / 2, 0); m_previewWidget->move((width() - Theme::materialPreviewImageSize) / 2, 0);
@ -57,12 +57,12 @@ void MaterialWidget::updatePreview(dust3d::Uuid materialId)
{ {
if (materialId != m_materialId) if (materialId != m_materialId)
return; return;
const Material *material = m_document->findMaterial(m_materialId); const Material* material = m_document->findMaterial(m_materialId);
if (!material) { if (!material) {
qDebug() << "Material not found:" << m_materialId; qDebug() << "Material not found:" << m_materialId;
return; return;
} }
ModelMesh *previewMesh = material->takePreviewMesh(); ModelMesh* previewMesh = material->takePreviewMesh();
m_previewWidget->updateMesh(previewMesh); m_previewWidget->updateMesh(previewMesh);
} }
@ -70,7 +70,7 @@ void MaterialWidget::updateName(dust3d::Uuid materialId)
{ {
if (materialId != m_materialId) if (materialId != m_materialId)
return; return;
const Material *material = m_document->findMaterial(m_materialId); const Material* material = m_document->findMaterial(m_materialId);
if (!material) { if (!material) {
qDebug() << "Material not found:" << m_materialId; qDebug() << "Material not found:" << m_materialId;
return; return;
@ -86,12 +86,12 @@ void MaterialWidget::updateCheckedState(bool checked)
setStyleSheet("#MaterialFrame {border: 1px solid transparent;}"); setStyleSheet("#MaterialFrame {border: 1px solid transparent;}");
} }
ModelWidget *MaterialWidget::previewWidget() ModelWidget* MaterialWidget::previewWidget()
{ {
return m_previewWidget; return m_previewWidget;
} }
void MaterialWidget::mouseDoubleClickEvent(QMouseEvent *event) void MaterialWidget::mouseDoubleClickEvent(QMouseEvent* event)
{ {
QFrame::mouseDoubleClickEvent(event); QFrame::mouseDoubleClickEvent(event);
emit modifyMaterial(m_materialId); emit modifyMaterial(m_materialId);

View File

@ -1,36 +1,38 @@
#ifndef DUST3D_APPLICATION_MATERIAL_WIDGET_H_ #ifndef DUST3D_APPLICATION_MATERIAL_WIDGET_H_
#define DUST3D_APPLICATION_MATERIAL_WIDGET_H_ #define DUST3D_APPLICATION_MATERIAL_WIDGET_H_
#include <QFrame>
#include <QLabel>
#include <QIcon>
#include <QPushButton>
#include "model_widget.h" #include "model_widget.h"
#include <QFrame>
#include <QIcon>
#include <QLabel>
#include <QPushButton>
class Document; class Document;
class MaterialWidget : public QFrame class MaterialWidget : public QFrame {
{
Q_OBJECT Q_OBJECT
signals: signals:
void modifyMaterial(dust3d::Uuid materialId); void modifyMaterial(dust3d::Uuid materialId);
public: public:
MaterialWidget(const Document *document, dust3d::Uuid materialId); MaterialWidget(const Document* document, dust3d::Uuid materialId);
static int preferredHeight(); static int preferredHeight();
ModelWidget *previewWidget(); ModelWidget* previewWidget();
protected: protected:
void mouseDoubleClickEvent(QMouseEvent *event) override; void mouseDoubleClickEvent(QMouseEvent* event) override;
void resizeEvent(QResizeEvent *event) override; void resizeEvent(QResizeEvent* event) override;
public slots: public slots:
void reload(); void reload();
void updatePreview(dust3d::Uuid materialId); void updatePreview(dust3d::Uuid materialId);
void updateName(dust3d::Uuid materialId); void updateName(dust3d::Uuid materialId);
void updateCheckedState(bool checked); void updateCheckedState(bool checked);
private: private:
dust3d::Uuid m_materialId; dust3d::Uuid m_materialId;
const Document *m_document = nullptr; const Document* m_document = nullptr;
ModelWidget *m_previewWidget = nullptr; ModelWidget* m_previewWidget = nullptr;
QLabel *m_nameLabel = nullptr; QLabel* m_nameLabel = nullptr;
}; };
#endif #endif

View File

@ -1,13 +1,13 @@
#include <dust3d/mesh/smooth_normal.h>
#include <dust3d/mesh/trim_vertices.h>
#include <QElapsedTimer>
#include <QDebug>
#include "mesh_generator.h" #include "mesh_generator.h"
#include "cut_face_preview.h" #include "cut_face_preview.h"
#include <QDebug>
#include <QElapsedTimer>
#include <dust3d/mesh/smooth_normal.h>
#include <dust3d/mesh/trim_vertices.h>
MeshGenerator::MeshGenerator(dust3d::Snapshot *snapshot) : MeshGenerator::MeshGenerator(dust3d::Snapshot* snapshot)
dust3d::MeshGenerator(snapshot) : dust3d::MeshGenerator(snapshot)
{ {
} }
@ -15,12 +15,12 @@ MeshGenerator::~MeshGenerator()
{ {
} }
std::map<dust3d::Uuid, std::unique_ptr<ModelMesh>> *MeshGenerator::takeComponentPreviewMeshes() std::map<dust3d::Uuid, std::unique_ptr<ModelMesh>>* MeshGenerator::takeComponentPreviewMeshes()
{ {
return m_componentPreviewMeshes.release(); return m_componentPreviewMeshes.release();
} }
MonochromeMesh *MeshGenerator::takeWireframeMesh() MonochromeMesh* MeshGenerator::takeWireframeMesh()
{ {
return m_wireframeMesh.release(); return m_wireframeMesh.release();
} }
@ -29,29 +29,28 @@ void MeshGenerator::process()
{ {
QElapsedTimer countTimeConsumed; QElapsedTimer countTimeConsumed;
countTimeConsumed.start(); countTimeConsumed.start();
generate(); generate();
if (nullptr != m_object) if (nullptr != m_object)
m_resultMesh = std::make_unique<ModelMesh>(*m_object); m_resultMesh = std::make_unique<ModelMesh>(*m_object);
m_componentPreviewMeshes = std::make_unique<std::map<dust3d::Uuid, std::unique_ptr<ModelMesh>>>(); m_componentPreviewMeshes = std::make_unique<std::map<dust3d::Uuid, std::unique_ptr<ModelMesh>>>();
for (const auto &componentId: m_generatedPreviewComponentIds) { for (const auto& componentId : m_generatedPreviewComponentIds) {
auto it = m_generatedComponentPreviews.find(componentId); auto it = m_generatedComponentPreviews.find(componentId);
if (it == m_generatedComponentPreviews.end()) if (it == m_generatedComponentPreviews.end())
continue; continue;
dust3d::trimVertices(&it->second.vertices, true); dust3d::trimVertices(&it->second.vertices, true);
for (auto &it: it->second.vertices) { for (auto& it : it->second.vertices) {
it *= 2.0; it *= 2.0;
} }
std::vector<dust3d::Vector3> previewTriangleNormals; std::vector<dust3d::Vector3> previewTriangleNormals;
previewTriangleNormals.reserve(it->second.triangles.size()); previewTriangleNormals.reserve(it->second.triangles.size());
for (const auto &face: it->second.triangles) { for (const auto& face : it->second.triangles) {
previewTriangleNormals.emplace_back(dust3d::Vector3::normal( previewTriangleNormals.emplace_back(dust3d::Vector3::normal(
it->second.vertices[face[0]], it->second.vertices[face[0]],
it->second.vertices[face[1]], it->second.vertices[face[1]],
it->second.vertices[face[2]] it->second.vertices[face[2]]));
));
} }
std::vector<std::vector<dust3d::Vector3>> previewTriangleVertexNormals; std::vector<std::vector<dust3d::Vector3>> previewTriangleVertexNormals;
dust3d::smoothNormal(it->second.vertices, dust3d::smoothNormal(it->second.vertices,
@ -70,14 +69,13 @@ void MeshGenerator::process()
if (nullptr != m_object) if (nullptr != m_object)
m_wireframeMesh = std::make_unique<MonochromeMesh>(*m_object); m_wireframeMesh = std::make_unique<MonochromeMesh>(*m_object);
qDebug() << "The mesh generation took" << countTimeConsumed.elapsed() << "milliseconds"; qDebug() << "The mesh generation took" << countTimeConsumed.elapsed() << "milliseconds";
emit finished(); emit finished();
} }
ModelMesh *MeshGenerator::takeResultMesh() ModelMesh* MeshGenerator::takeResultMesh()
{ {
return m_resultMesh.release(); return m_resultMesh.release();
} }

View File

@ -1,26 +1,26 @@
#ifndef DUST3D_APPLICATION_MESH_GENERATOR_H_ #ifndef DUST3D_APPLICATION_MESH_GENERATOR_H_
#define DUST3D_APPLICATION_MESH_GENERATOR_H_ #define DUST3D_APPLICATION_MESH_GENERATOR_H_
#include <memory>
#include <QObject>
#include <QImage>
#include <dust3d/mesh/mesh_generator.h>
#include "model_mesh.h" #include "model_mesh.h"
#include "monochrome_mesh.h" #include "monochrome_mesh.h"
#include <QImage>
#include <QObject>
#include <dust3d/mesh/mesh_generator.h>
#include <memory>
class MeshGenerator : public QObject, public dust3d::MeshGenerator class MeshGenerator : public QObject, public dust3d::MeshGenerator {
{
Q_OBJECT Q_OBJECT
public: public:
MeshGenerator(dust3d::Snapshot *snapshot); MeshGenerator(dust3d::Snapshot* snapshot);
~MeshGenerator(); ~MeshGenerator();
ModelMesh *takeResultMesh(); ModelMesh* takeResultMesh();
std::map<dust3d::Uuid, std::unique_ptr<ModelMesh>> *takeComponentPreviewMeshes(); std::map<dust3d::Uuid, std::unique_ptr<ModelMesh>>* takeComponentPreviewMeshes();
MonochromeMesh *takeWireframeMesh(); MonochromeMesh* takeWireframeMesh();
public slots: public slots:
void process(); void process();
signals: signals:
void finished(); void finished();
private: private:
std::unique_ptr<ModelMesh> m_resultMesh; std::unique_ptr<ModelMesh> m_resultMesh;
std::unique_ptr<std::map<dust3d::Uuid, std::unique_ptr<ModelMesh>>> m_componentPreviewMeshes; std::unique_ptr<std::map<dust3d::Uuid, std::unique_ptr<ModelMesh>>> m_componentPreviewMeshes;

View File

@ -1,20 +1,20 @@
#include <QDebug>
#include "mesh_preview_images_generator.h" #include "mesh_preview_images_generator.h"
#include "theme.h" #include "theme.h"
#include <QDebug>
void MeshPreviewImagesGenerator::addInput(const dust3d::Uuid &inputId, std::unique_ptr<ModelMesh> previewMesh, bool useFrontView) void MeshPreviewImagesGenerator::addInput(const dust3d::Uuid& inputId, std::unique_ptr<ModelMesh> previewMesh, bool useFrontView)
{ {
m_previewInputMap.insert({inputId, PreviewInput {std::move(previewMesh), useFrontView}}); m_previewInputMap.insert({ inputId, PreviewInput { std::move(previewMesh), useFrontView } });
} }
void MeshPreviewImagesGenerator::process() void MeshPreviewImagesGenerator::process()
{ {
generate(); generate();
emit finished(); emit finished();
} }
std::map<dust3d::Uuid, QImage> *MeshPreviewImagesGenerator::takeImages() std::map<dust3d::Uuid, QImage>* MeshPreviewImagesGenerator::takeImages()
{ {
return m_partImages.release(); return m_partImages.release();
} }
@ -22,10 +22,10 @@ std::map<dust3d::Uuid, QImage> *MeshPreviewImagesGenerator::takeImages()
void MeshPreviewImagesGenerator::generate() void MeshPreviewImagesGenerator::generate()
{ {
m_partImages = std::make_unique<std::map<dust3d::Uuid, QImage>>(); m_partImages = std::make_unique<std::map<dust3d::Uuid, QImage>>();
m_offscreenRender->setZRotation(0); m_offscreenRender->setZRotation(0);
m_offscreenRender->setEyePosition(QVector3D(0, 0, -4.0)); m_offscreenRender->setEyePosition(QVector3D(0, 0, -4.0));
for (auto &it: m_previewInputMap) { for (auto& it : m_previewInputMap) {
if (it.second.useFrontView) { if (it.second.useFrontView) {
m_offscreenRender->setXRotation(0); m_offscreenRender->setXRotation(0);
m_offscreenRender->setYRotation(0); m_offscreenRender->setYRotation(0);

View File

@ -1,43 +1,42 @@
#ifndef DUST3D_APPLICATION_MESH_PREVIEW_IMAGES_GENERATOR_H_ #ifndef DUST3D_APPLICATION_MESH_PREVIEW_IMAGES_GENERATOR_H_
#define DUST3D_APPLICATION_MESH_PREVIEW_IMAGES_GENERATOR_H_ #define DUST3D_APPLICATION_MESH_PREVIEW_IMAGES_GENERATOR_H_
#include <QObject>
#include <QImage>
#include <memory>
#include <map>
#include <dust3d/base/uuid.h>
#include "model_offscreen_render.h" #include "model_offscreen_render.h"
#include <QImage>
#include <QObject>
#include <dust3d/base/uuid.h>
#include <map>
#include <memory>
class MeshPreviewImagesGenerator : public QObject class MeshPreviewImagesGenerator : public QObject {
{
Q_OBJECT Q_OBJECT
public: public:
MeshPreviewImagesGenerator(ModelOffscreenRender *modelOffscreenRender) : MeshPreviewImagesGenerator(ModelOffscreenRender* modelOffscreenRender)
m_offscreenRender(modelOffscreenRender) : m_offscreenRender(modelOffscreenRender)
{ {
} }
struct PreviewInput struct PreviewInput {
{
std::unique_ptr<ModelMesh> mesh; std::unique_ptr<ModelMesh> mesh;
bool useFrontView = false; bool useFrontView = false;
}; };
~MeshPreviewImagesGenerator() ~MeshPreviewImagesGenerator()
{ {
delete m_offscreenRender; delete m_offscreenRender;
} }
void addInput(const dust3d::Uuid &inputId, std::unique_ptr<ModelMesh> previewMesh, bool useFrontView=false); void addInput(const dust3d::Uuid& inputId, std::unique_ptr<ModelMesh> previewMesh, bool useFrontView = false);
void generate(); void generate();
std::map<dust3d::Uuid, QImage> *takeImages(); std::map<dust3d::Uuid, QImage>* takeImages();
signals: signals:
void finished(); void finished();
public slots: public slots:
void process(); void process();
private: private:
std::map<dust3d::Uuid, PreviewInput> m_previewInputMap; std::map<dust3d::Uuid, PreviewInput> m_previewInputMap;
ModelOffscreenRender *m_offscreenRender = nullptr; ModelOffscreenRender* m_offscreenRender = nullptr;
std::unique_ptr<std::map<dust3d::Uuid, QImage>> m_partImages; std::unique_ptr<std::map<dust3d::Uuid, QImage>> m_partImages;
}; };

View File

@ -1,9 +1,9 @@
#include <QGuiApplication>
#include <dust3d/uv/unwrap_uv.h>
#include <dust3d/mesh/resolve_triangle_tangent.h>
#include "mesh_result_post_processor.h" #include "mesh_result_post_processor.h"
#include <QGuiApplication>
#include <dust3d/mesh/resolve_triangle_tangent.h>
#include <dust3d/uv/unwrap_uv.h>
MeshResultPostProcessor::MeshResultPostProcessor(const dust3d::Object &object) MeshResultPostProcessor::MeshResultPostProcessor(const dust3d::Object& object)
{ {
m_object = new dust3d::Object; m_object = new dust3d::Object;
*m_object = object; *m_object = object;
@ -14,9 +14,9 @@ MeshResultPostProcessor::~MeshResultPostProcessor()
delete m_object; delete m_object;
} }
dust3d::Object *MeshResultPostProcessor::takePostProcessedObject() dust3d::Object* MeshResultPostProcessor::takePostProcessedObject()
{ {
dust3d::Object *object = m_object; dust3d::Object* object = m_object;
m_object = nullptr; m_object = nullptr;
return object; return object;
} }
@ -32,7 +32,7 @@ void MeshResultPostProcessor::poseProcess()
m_object->setTriangleVertexUvs(triangleVertexUvs); m_object->setTriangleVertexUvs(triangleVertexUvs);
m_object->setPartUvRects(partUvRects); m_object->setPartUvRects(partUvRects);
} }
{ {
std::vector<dust3d::Vector3> triangleTangents; std::vector<dust3d::Vector3> triangleTangents;
dust3d::resolveTriangleTangent(*m_object, triangleTangents); dust3d::resolveTriangleTangent(*m_object, triangleTangents);

View File

@ -4,20 +4,20 @@
#include <QObject> #include <QObject>
#include <dust3d/base/object.h> #include <dust3d/base/object.h>
class MeshResultPostProcessor : public QObject class MeshResultPostProcessor : public QObject {
{
Q_OBJECT Q_OBJECT
public: public:
MeshResultPostProcessor(const dust3d::Object &object); MeshResultPostProcessor(const dust3d::Object& object);
~MeshResultPostProcessor(); ~MeshResultPostProcessor();
dust3d::Object *takePostProcessedObject(); dust3d::Object* takePostProcessedObject();
void poseProcess(); void poseProcess();
signals: signals:
void finished(); void finished();
public slots: public slots:
void process(); void process();
private: private:
dust3d::Object *m_object = nullptr; dust3d::Object* m_object = nullptr;
}; };
#endif #endif

View File

@ -1,20 +1,19 @@
#include <assert.h>
#include <QTextStream>
#include <QFile>
#include <cmath>
#include "model_mesh.h" #include "model_mesh.h"
#include "version.h" #include "version.h"
#include <QFile>
#include <QTextStream>
#include <assert.h>
#include <cmath>
float ModelMesh::m_defaultMetalness = 0.0; float ModelMesh::m_defaultMetalness = 0.0;
float ModelMesh::m_defaultRoughness = 1.0; float ModelMesh::m_defaultRoughness = 1.0;
ModelMesh::ModelMesh(const ModelMesh &mesh) : ModelMesh::ModelMesh(const ModelMesh& mesh)
m_triangleVertices(nullptr), : m_triangleVertices(nullptr)
m_triangleVertexCount(0), , m_triangleVertexCount(0)
m_textureImage(nullptr) , m_textureImage(nullptr)
{ {
if (nullptr != mesh.m_triangleVertices && if (nullptr != mesh.m_triangleVertices && mesh.m_triangleVertexCount > 0) {
mesh.m_triangleVertexCount > 0) {
this->m_triangleVertices = new ModelOpenGLVertex[mesh.m_triangleVertexCount]; this->m_triangleVertices = new ModelOpenGLVertex[mesh.m_triangleVertexCount];
this->m_triangleVertexCount = mesh.m_triangleVertexCount; this->m_triangleVertexCount = mesh.m_triangleVertexCount;
for (int i = 0; i < mesh.m_triangleVertexCount; i++) for (int i = 0; i < mesh.m_triangleVertexCount; i++)
@ -42,39 +41,39 @@ void ModelMesh::removeColor()
{ {
delete this->m_textureImage; delete this->m_textureImage;
this->m_textureImage = nullptr; this->m_textureImage = nullptr;
delete this->m_normalMapImage; delete this->m_normalMapImage;
this->m_normalMapImage = nullptr; this->m_normalMapImage = nullptr;
delete this->m_metalnessRoughnessAmbientOcclusionMapImage; delete this->m_metalnessRoughnessAmbientOcclusionMapImage;
this->m_metalnessRoughnessAmbientOcclusionMapImage = nullptr; this->m_metalnessRoughnessAmbientOcclusionMapImage = nullptr;
this->m_hasMetalnessInImage = false; this->m_hasMetalnessInImage = false;
this->m_hasRoughnessInImage = false; this->m_hasRoughnessInImage = false;
this->m_hasAmbientOcclusionInImage = false; this->m_hasAmbientOcclusionInImage = false;
for (int i = 0; i < this->m_triangleVertexCount; ++i) { for (int i = 0; i < this->m_triangleVertexCount; ++i) {
auto &vertex = this->m_triangleVertices[i]; auto& vertex = this->m_triangleVertices[i];
vertex.colorR = 1.0; vertex.colorR = 1.0;
vertex.colorG = 1.0; vertex.colorG = 1.0;
vertex.colorB = 1.0; vertex.colorB = 1.0;
} }
} }
ModelMesh::ModelMesh(ModelOpenGLVertex *triangleVertices, int vertexNum) : ModelMesh::ModelMesh(ModelOpenGLVertex* triangleVertices, int vertexNum)
m_triangleVertices(triangleVertices), : m_triangleVertices(triangleVertices)
m_triangleVertexCount(vertexNum), , m_triangleVertexCount(vertexNum)
m_textureImage(nullptr) , m_textureImage(nullptr)
{ {
} }
ModelMesh::ModelMesh(const std::vector<dust3d::Vector3> &vertices, ModelMesh::ModelMesh(const std::vector<dust3d::Vector3>& vertices,
const std::vector<std::vector<size_t>> &triangles, const std::vector<std::vector<size_t>>& triangles,
const std::vector<std::vector<dust3d::Vector3>> &triangleVertexNormals, const std::vector<std::vector<dust3d::Vector3>>& triangleVertexNormals,
const dust3d::Color &color, const dust3d::Color& color,
float metalness, float metalness,
float roughness, float roughness,
const std::vector<std::tuple<dust3d::Color, float/*metalness*/, float/*roughness*/>> *vertexProperties) const std::vector<std::tuple<dust3d::Color, float /*metalness*/, float /*roughness*/>>* vertexProperties)
{ {
m_triangleVertexCount = (int)triangles.size() * 3; m_triangleVertexCount = (int)triangles.size() * 3;
m_triangleVertices = new ModelOpenGLVertex[m_triangleVertexCount]; m_triangleVertices = new ModelOpenGLVertex[m_triangleVertexCount];
@ -82,9 +81,9 @@ ModelMesh::ModelMesh(const std::vector<dust3d::Vector3> &vertices,
for (size_t i = 0; i < triangles.size(); ++i) { for (size_t i = 0; i < triangles.size(); ++i) {
for (auto j = 0; j < 3; j++) { for (auto j = 0; j < 3; j++) {
int vertexIndex = (int)triangles[i][j]; int vertexIndex = (int)triangles[i][j];
const dust3d::Vector3 *srcVert = &vertices[vertexIndex]; const dust3d::Vector3* srcVert = &vertices[vertexIndex];
const dust3d::Vector3 *srcNormal = &(triangleVertexNormals)[i][j]; const dust3d::Vector3* srcNormal = &(triangleVertexNormals)[i][j];
ModelOpenGLVertex *dest = &m_triangleVertices[destIndex]; ModelOpenGLVertex* dest = &m_triangleVertices[destIndex];
dest->posX = srcVert->x(); dest->posX = srcVert->x();
dest->posY = srcVert->y(); dest->posY = srcVert->y();
dest->posZ = srcVert->z(); dest->posZ = srcVert->z();
@ -101,7 +100,7 @@ ModelMesh::ModelMesh(const std::vector<dust3d::Vector3> &vertices,
dest->metalness = metalness; dest->metalness = metalness;
dest->roughness = roughness; dest->roughness = roughness;
} else { } else {
const auto &property = (*vertexProperties)[vertexIndex]; const auto& property = (*vertexProperties)[vertexIndex];
dest->colorR = std::get<0>(property).r(); dest->colorR = std::get<0>(property).r();
dest->colorG = std::get<0>(property).g(); dest->colorG = std::get<0>(property).g();
dest->colorB = std::get<0>(property).b(); dest->colorB = std::get<0>(property).b();
@ -117,21 +116,21 @@ ModelMesh::ModelMesh(const std::vector<dust3d::Vector3> &vertices,
} }
} }
ModelMesh::ModelMesh(dust3d::Object &object) : ModelMesh::ModelMesh(dust3d::Object& object)
m_triangleVertices(nullptr), : m_triangleVertices(nullptr)
m_triangleVertexCount(0), , m_triangleVertexCount(0)
m_textureImage(nullptr) , m_textureImage(nullptr)
{ {
m_meshId = object.meshId; m_meshId = object.meshId;
m_vertices = object.vertices; m_vertices = object.vertices;
m_faces = object.triangleAndQuads; m_faces = object.triangleAndQuads;
std::map<std::pair<dust3d::Uuid, dust3d::Uuid>, const dust3d::ObjectNode *> nodeMap; std::map<std::pair<dust3d::Uuid, dust3d::Uuid>, const dust3d::ObjectNode*> nodeMap;
for (size_t i = 0; i < object.nodes.size(); ++i) { for (size_t i = 0; i < object.nodes.size(); ++i) {
const auto &node = object.nodes[i]; const auto& node = object.nodes[i];
nodeMap.insert({{node.partId, node.nodeId}, &node}); nodeMap.insert({ { node.partId, node.nodeId }, &node });
} }
m_triangleVertexCount = (int)object.triangles.size() * 3; m_triangleVertexCount = (int)object.triangles.size() * 3;
m_triangleVertices = new ModelOpenGLVertex[m_triangleVertexCount]; m_triangleVertices = new ModelOpenGLVertex[m_triangleVertexCount];
int destIndex = 0; int destIndex = 0;
@ -142,20 +141,20 @@ ModelMesh::ModelMesh(dust3d::Object &object) :
const dust3d::Vector2 defaultUv = dust3d::Vector2(0, 0); const dust3d::Vector2 defaultUv = dust3d::Vector2(0, 0);
const dust3d::Vector3 defaultTangent = dust3d::Vector3(0, 0, 0); const dust3d::Vector3 defaultTangent = dust3d::Vector3(0, 0, 0);
for (size_t i = 0; i < object.triangles.size(); ++i) { for (size_t i = 0; i < object.triangles.size(); ++i) {
const auto &triangleColor = &object.triangleColors[i]; const auto& triangleColor = &object.triangleColors[i];
for (auto j = 0; j < 3; j++) { for (auto j = 0; j < 3; j++) {
int vertexIndex = (int)object.triangles[i][j]; int vertexIndex = (int)object.triangles[i][j];
const dust3d::Vector3 *srcVert = &object.vertices[vertexIndex]; const dust3d::Vector3* srcVert = &object.vertices[vertexIndex];
const dust3d::Vector3 *srcNormal = &defaultNormal; const dust3d::Vector3* srcNormal = &defaultNormal;
if (triangleVertexNormals) if (triangleVertexNormals)
srcNormal = &(*triangleVertexNormals)[i][j]; srcNormal = &(*triangleVertexNormals)[i][j];
const dust3d::Vector2 *srcUv = &defaultUv; const dust3d::Vector2* srcUv = &defaultUv;
if (triangleVertexUvs) if (triangleVertexUvs)
srcUv = &(*triangleVertexUvs)[i][j]; srcUv = &(*triangleVertexUvs)[i][j];
const dust3d::Vector3 *srcTangent = &defaultTangent; const dust3d::Vector3* srcTangent = &defaultTangent;
if (triangleTangents) if (triangleTangents)
srcTangent = &(*triangleTangents)[i]; srcTangent = &(*triangleTangents)[i];
ModelOpenGLVertex *dest = &m_triangleVertices[destIndex]; ModelOpenGLVertex* dest = &m_triangleVertices[destIndex];
dest->colorR = triangleColor->r(); dest->colorR = triangleColor->r();
dest->colorG = triangleColor->g(); dest->colorG = triangleColor->g();
dest->colorB = triangleColor->b(); dest->colorB = triangleColor->b();
@ -184,10 +183,10 @@ ModelMesh::ModelMesh(dust3d::Object &object) :
} }
} }
ModelMesh::ModelMesh() : ModelMesh::ModelMesh()
m_triangleVertices(nullptr), : m_triangleVertices(nullptr)
m_triangleVertexCount(0), , m_triangleVertexCount(0)
m_textureImage(nullptr) , m_textureImage(nullptr)
{ {
} }
@ -200,22 +199,22 @@ ModelMesh::~ModelMesh()
delete m_metalnessRoughnessAmbientOcclusionMapImage; delete m_metalnessRoughnessAmbientOcclusionMapImage;
} }
const std::vector<dust3d::Vector3> &ModelMesh::vertices() const std::vector<dust3d::Vector3>& ModelMesh::vertices()
{ {
return m_vertices; return m_vertices;
} }
const std::vector<std::vector<size_t>> &ModelMesh::faces() const std::vector<std::vector<size_t>>& ModelMesh::faces()
{ {
return m_faces; return m_faces;
} }
const std::vector<dust3d::Vector3> &ModelMesh::triangulatedVertices() const std::vector<dust3d::Vector3>& ModelMesh::triangulatedVertices()
{ {
return m_triangulatedVertices; return m_triangulatedVertices;
} }
ModelOpenGLVertex *ModelMesh::triangleVertices() ModelOpenGLVertex* ModelMesh::triangleVertices()
{ {
return m_triangleVertices; return m_triangleVertices;
} }
@ -225,53 +224,53 @@ int ModelMesh::triangleVertexCount()
return m_triangleVertexCount; return m_triangleVertexCount;
} }
void ModelMesh::setTextureImage(QImage *textureImage) void ModelMesh::setTextureImage(QImage* textureImage)
{ {
m_textureImage = textureImage; m_textureImage = textureImage;
} }
const QImage *ModelMesh::textureImage() const QImage* ModelMesh::textureImage()
{ {
return m_textureImage; return m_textureImage;
} }
QImage *ModelMesh::takeTextureImage() QImage* ModelMesh::takeTextureImage()
{ {
auto image = m_textureImage; auto image = m_textureImage;
m_textureImage = nullptr; m_textureImage = nullptr;
return image; return image;
} }
void ModelMesh::setNormalMapImage(QImage *normalMapImage) void ModelMesh::setNormalMapImage(QImage* normalMapImage)
{ {
m_normalMapImage = normalMapImage; m_normalMapImage = normalMapImage;
} }
const QImage *ModelMesh::normalMapImage() const QImage* ModelMesh::normalMapImage()
{ {
return m_normalMapImage; return m_normalMapImage;
} }
QImage *ModelMesh::takeNormalMapImage() QImage* ModelMesh::takeNormalMapImage()
{ {
auto image = m_normalMapImage; auto image = m_normalMapImage;
m_normalMapImage = nullptr; m_normalMapImage = nullptr;
return image; return image;
} }
const QImage *ModelMesh::metalnessRoughnessAmbientOcclusionMapImage() const QImage* ModelMesh::metalnessRoughnessAmbientOcclusionMapImage()
{ {
return m_metalnessRoughnessAmbientOcclusionMapImage; return m_metalnessRoughnessAmbientOcclusionMapImage;
} }
QImage *ModelMesh::takeMetalnessRoughnessAmbientOcclusionMapImage() QImage* ModelMesh::takeMetalnessRoughnessAmbientOcclusionMapImage()
{ {
auto image = m_metalnessRoughnessAmbientOcclusionMapImage; auto image = m_metalnessRoughnessAmbientOcclusionMapImage;
m_metalnessRoughnessAmbientOcclusionMapImage = nullptr; m_metalnessRoughnessAmbientOcclusionMapImage = nullptr;
return image; return image;
} }
void ModelMesh::setMetalnessRoughnessAmbientOcclusionMapImage(QImage *image) void ModelMesh::setMetalnessRoughnessAmbientOcclusionMapImage(QImage* image)
{ {
m_metalnessRoughnessAmbientOcclusionMapImage = image; m_metalnessRoughnessAmbientOcclusionMapImage = image;
} }
@ -306,24 +305,24 @@ void ModelMesh::setHasAmbientOcclusionInImage(bool hasInImage)
m_hasAmbientOcclusionInImage = hasInImage; m_hasAmbientOcclusionInImage = hasInImage;
} }
void ModelMesh::exportAsObj(QTextStream *textStream) void ModelMesh::exportAsObj(QTextStream* textStream)
{ {
auto &stream = *textStream; auto& stream = *textStream;
stream << "# " << APP_NAME << " " << APP_HUMAN_VER << endl; stream << "# " << APP_NAME << " " << APP_HUMAN_VER << endl;
stream << "# " << APP_HOMEPAGE_URL << endl; stream << "# " << APP_HOMEPAGE_URL << endl;
for (std::vector<dust3d::Vector3>::const_iterator it = vertices().begin() ; it != vertices().end(); ++it) { for (std::vector<dust3d::Vector3>::const_iterator it = vertices().begin(); it != vertices().end(); ++it) {
stream << "v " << QString::number((*it).x()) << " " << QString::number((*it).y()) << " " << QString::number((*it).z()) << endl; stream << "v " << QString::number((*it).x()) << " " << QString::number((*it).y()) << " " << QString::number((*it).z()) << endl;
} }
for (std::vector<std::vector<size_t>>::const_iterator it = faces().begin() ; it != faces().end(); ++it) { for (std::vector<std::vector<size_t>>::const_iterator it = faces().begin(); it != faces().end(); ++it) {
stream << "f"; stream << "f";
for (std::vector<size_t>::const_iterator subIt = (*it).begin() ; subIt != (*it).end(); ++subIt) { for (std::vector<size_t>::const_iterator subIt = (*it).begin(); subIt != (*it).end(); ++subIt) {
stream << " " << QString::number((1 + *subIt)); stream << " " << QString::number((1 + *subIt));
} }
stream << endl; stream << endl;
} }
} }
void ModelMesh::exportAsObj(const QString &filename) void ModelMesh::exportAsObj(const QString& filename)
{ {
QFile file(filename); QFile file(filename);
if (file.open(QIODevice::WriteOnly)) { if (file.open(QIODevice::WriteOnly)) {
@ -332,12 +331,12 @@ void ModelMesh::exportAsObj(const QString &filename)
} }
} }
void ModelMesh::updateTriangleVertices(ModelOpenGLVertex *triangleVertices, int triangleVertexCount) void ModelMesh::updateTriangleVertices(ModelOpenGLVertex* triangleVertices, int triangleVertexCount)
{ {
delete[] m_triangleVertices; delete[] m_triangleVertices;
m_triangleVertices = 0; m_triangleVertices = 0;
m_triangleVertexCount = 0; m_triangleVertexCount = 0;
m_triangleVertices = triangleVertices; m_triangleVertices = triangleVertices;
m_triangleVertexCount = triangleVertexCount; m_triangleVertexCount = triangleVertexCount;
} }

View File

@ -1,44 +1,43 @@
#ifndef DUST3D_APPLICATION_MODEL_MESH_H_ #ifndef DUST3D_APPLICATION_MODEL_MESH_H_
#define DUST3D_APPLICATION_MODEL_MESH_H_ #define DUST3D_APPLICATION_MODEL_MESH_H_
#include <QObject> #include "model_opengl_vertex.h"
#include <vector>
#include <QImage> #include <QImage>
#include <QObject>
#include <QTextStream> #include <QTextStream>
#include <dust3d/base/vector3.h>
#include <dust3d/base/color.h> #include <dust3d/base/color.h>
#include <dust3d/base/object.h> #include <dust3d/base/object.h>
#include "model_opengl_vertex.h" #include <dust3d/base/vector3.h>
#include <vector>
class ModelMesh class ModelMesh {
{
public: public:
ModelMesh(const std::vector<dust3d::Vector3> &vertices, ModelMesh(const std::vector<dust3d::Vector3>& vertices,
const std::vector<std::vector<size_t>> &triangles, const std::vector<std::vector<size_t>>& triangles,
const std::vector<std::vector<dust3d::Vector3>> &triangleVertexNormals, const std::vector<std::vector<dust3d::Vector3>>& triangleVertexNormals,
const dust3d::Color &color=dust3d::Color::createWhite(), const dust3d::Color& color = dust3d::Color::createWhite(),
float metalness=0.0, float metalness = 0.0,
float roughness=1.0, float roughness = 1.0,
const std::vector<std::tuple<dust3d::Color, float/*metalness*/, float/*roughness*/>> *vertexProperties=nullptr); const std::vector<std::tuple<dust3d::Color, float /*metalness*/, float /*roughness*/>>* vertexProperties = nullptr);
ModelMesh(dust3d::Object &object); ModelMesh(dust3d::Object& object);
ModelMesh(ModelOpenGLVertex *triangleVertices, int vertexNum); ModelMesh(ModelOpenGLVertex* triangleVertices, int vertexNum);
ModelMesh(const ModelMesh &mesh); ModelMesh(const ModelMesh& mesh);
ModelMesh(); ModelMesh();
~ModelMesh(); ~ModelMesh();
ModelOpenGLVertex *triangleVertices(); ModelOpenGLVertex* triangleVertices();
int triangleVertexCount(); int triangleVertexCount();
const std::vector<dust3d::Vector3> &vertices(); const std::vector<dust3d::Vector3>& vertices();
const std::vector<std::vector<size_t>> &faces(); const std::vector<std::vector<size_t>>& faces();
const std::vector<dust3d::Vector3> &triangulatedVertices(); const std::vector<dust3d::Vector3>& triangulatedVertices();
void setTextureImage(QImage *textureImage); void setTextureImage(QImage* textureImage);
const QImage *textureImage(); const QImage* textureImage();
QImage *takeTextureImage(); QImage* takeTextureImage();
void setNormalMapImage(QImage *normalMapImage); void setNormalMapImage(QImage* normalMapImage);
const QImage *normalMapImage(); const QImage* normalMapImage();
QImage *takeNormalMapImage(); QImage* takeNormalMapImage();
const QImage *metalnessRoughnessAmbientOcclusionMapImage(); const QImage* metalnessRoughnessAmbientOcclusionMapImage();
QImage *takeMetalnessRoughnessAmbientOcclusionMapImage(); QImage* takeMetalnessRoughnessAmbientOcclusionMapImage();
void setMetalnessRoughnessAmbientOcclusionMapImage(QImage *image); void setMetalnessRoughnessAmbientOcclusionMapImage(QImage* image);
bool hasMetalnessInImage(); bool hasMetalnessInImage();
void setHasMetalnessInImage(bool hasInImage); void setHasMetalnessInImage(bool hasInImage);
bool hasRoughnessInImage(); bool hasRoughnessInImage();
@ -47,21 +46,22 @@ public:
void setHasAmbientOcclusionInImage(bool hasInImage); void setHasAmbientOcclusionInImage(bool hasInImage);
static float m_defaultMetalness; static float m_defaultMetalness;
static float m_defaultRoughness; static float m_defaultRoughness;
void exportAsObj(const QString &filename); void exportAsObj(const QString& filename);
void exportAsObj(QTextStream *textStream); void exportAsObj(QTextStream* textStream);
void updateTriangleVertices(ModelOpenGLVertex *triangleVertices, int triangleVertexCount); void updateTriangleVertices(ModelOpenGLVertex* triangleVertices, int triangleVertexCount);
quint64 meshId() const; quint64 meshId() const;
void setMeshId(quint64 id); void setMeshId(quint64 id);
void removeColor(); void removeColor();
private: private:
ModelOpenGLVertex *m_triangleVertices = nullptr; ModelOpenGLVertex* m_triangleVertices = nullptr;
int m_triangleVertexCount = 0; int m_triangleVertexCount = 0;
std::vector<dust3d::Vector3> m_vertices; std::vector<dust3d::Vector3> m_vertices;
std::vector<std::vector<size_t>> m_faces; std::vector<std::vector<size_t>> m_faces;
std::vector<dust3d::Vector3> m_triangulatedVertices; std::vector<dust3d::Vector3> m_triangulatedVertices;
QImage *m_textureImage = nullptr; QImage* m_textureImage = nullptr;
QImage *m_normalMapImage = nullptr; QImage* m_normalMapImage = nullptr;
QImage *m_metalnessRoughnessAmbientOcclusionMapImage = nullptr; QImage* m_metalnessRoughnessAmbientOcclusionMapImage = nullptr;
bool m_hasMetalnessInImage = false; bool m_hasMetalnessInImage = false;
bool m_hasRoughnessInImage = false; bool m_hasRoughnessInImage = false;
bool m_hasAmbientOcclusionInImage = false; bool m_hasAmbientOcclusionInImage = false;

View File

@ -2,10 +2,10 @@
#include "model_opengl_object.h" #include "model_opengl_object.h"
#include "model_opengl_program.h" #include "model_opengl_program.h"
ModelOffscreenRender::ModelOffscreenRender(const QSurfaceFormat &format, QScreen *targetScreen): ModelOffscreenRender::ModelOffscreenRender(const QSurfaceFormat& format, QScreen* targetScreen)
QOffscreenSurface(targetScreen), : QOffscreenSurface(targetScreen)
m_context(nullptr), , m_context(nullptr)
m_mesh(nullptr) , m_mesh(nullptr)
{ {
setFormat(format); setFormat(format);
create(); create();
@ -13,11 +13,11 @@ ModelOffscreenRender::ModelOffscreenRender(const QSurfaceFormat &format, QScreen
ModelOffscreenRender::~ModelOffscreenRender() ModelOffscreenRender::~ModelOffscreenRender()
{ {
// FIXME: If delete m_renderFbo inside toImage, // FIXME: If delete m_renderFbo inside toImage,
// sometimes, the application will freeze, maybe there are dead locks inside the destruction call // sometimes, the application will freeze, maybe there are dead locks inside the destruction call
// move it here can make sure it will be deleted on the main GUI thread to avoid dead locks // move it here can make sure it will be deleted on the main GUI thread to avoid dead locks
delete m_renderFbo; delete m_renderFbo;
destroy(); destroy();
delete m_mesh; delete m_mesh;
} }
@ -37,28 +37,28 @@ void ModelOffscreenRender::setZRotation(int angle)
m_zRot = angle; m_zRot = angle;
} }
void ModelOffscreenRender::setEyePosition(const QVector3D &eyePosition) void ModelOffscreenRender::setEyePosition(const QVector3D& eyePosition)
{ {
m_eyePosition = eyePosition; m_eyePosition = eyePosition;
} }
void ModelOffscreenRender::setMoveToPosition(const QVector3D &moveToPosition) void ModelOffscreenRender::setMoveToPosition(const QVector3D& moveToPosition)
{ {
m_moveToPosition = moveToPosition; m_moveToPosition = moveToPosition;
} }
void ModelOffscreenRender::setRenderThread(QThread *thread) void ModelOffscreenRender::setRenderThread(QThread* thread)
{ {
moveToThread(thread); moveToThread(thread);
} }
void ModelOffscreenRender::updateMesh(ModelMesh *mesh) void ModelOffscreenRender::updateMesh(ModelMesh* mesh)
{ {
delete m_mesh; delete m_mesh;
m_mesh = mesh; m_mesh = mesh;
} }
QImage ModelOffscreenRender::toImage(const QSize &size) QImage ModelOffscreenRender::toImage(const QSize& size)
{ {
QImage image; QImage image;
@ -105,7 +105,7 @@ QImage ModelOffscreenRender::toImage(const QSize &size)
m_renderFbo = new QOpenGLFramebufferObject(size, format); m_renderFbo = new QOpenGLFramebufferObject(size, format);
m_renderFbo->bind(); m_renderFbo->bind();
QOpenGLFunctions *f = m_context->functions(); QOpenGLFunctions* f = m_context->functions();
f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
f->glEnable(GL_BLEND); f->glEnable(GL_BLEND);
f->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); f->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

View File

@ -1,34 +1,34 @@
#ifndef DUST3D_APPLICATION_MODEL_OFFSCREEN_RENDER_H_ #ifndef DUST3D_APPLICATION_MODEL_OFFSCREEN_RENDER_H_
#define DUST3D_APPLICATION_MODEL_OFFSCREEN_RENDER_H_ #define DUST3D_APPLICATION_MODEL_OFFSCREEN_RENDER_H_
#include "model_mesh.h"
#include <QOffscreenSurface> #include <QOffscreenSurface>
#include <QOpenGLFramebufferObject> #include <QOpenGLFramebufferObject>
#include <QSurfaceFormat> #include <QSurfaceFormat>
#include <QVector3D> #include <QVector3D>
#include "model_mesh.h"
class ModelOffscreenRender: public QOffscreenSurface class ModelOffscreenRender : public QOffscreenSurface {
{
public: public:
ModelOffscreenRender(const QSurfaceFormat &format, QScreen *targetScreen=Q_NULLPTR); ModelOffscreenRender(const QSurfaceFormat& format, QScreen* targetScreen = Q_NULLPTR);
~ModelOffscreenRender(); ~ModelOffscreenRender();
void setXRotation(int angle); void setXRotation(int angle);
void setYRotation(int angle); void setYRotation(int angle);
void setZRotation(int angle); void setZRotation(int angle);
void setEyePosition(const QVector3D &eyePosition); void setEyePosition(const QVector3D& eyePosition);
void setMoveToPosition(const QVector3D &moveToPosition); void setMoveToPosition(const QVector3D& moveToPosition);
void setRenderThread(QThread *thread); void setRenderThread(QThread* thread);
void updateMesh(ModelMesh *mesh); void updateMesh(ModelMesh* mesh);
QImage toImage(const QSize &size); QImage toImage(const QSize& size);
private: private:
int m_xRot = 0; int m_xRot = 0;
int m_yRot = 0; int m_yRot = 0;
int m_zRot = 0; int m_zRot = 0;
QVector3D m_eyePosition; QVector3D m_eyePosition;
QVector3D m_moveToPosition; QVector3D m_moveToPosition;
QOpenGLContext *m_context = nullptr; QOpenGLContext* m_context = nullptr;
QOpenGLFramebufferObject *m_renderFbo = nullptr; QOpenGLFramebufferObject* m_renderFbo = nullptr;
ModelMesh *m_mesh = nullptr; ModelMesh* m_mesh = nullptr;
}; };
#endif #endif

View File

@ -1,7 +1,7 @@
#include <dust3d/base/debug.h>
#include <QOpenGLFunctions>
#include <QOpenGLContext>
#include "model_opengl_object.h" #include "model_opengl_object.h"
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <dust3d/base/debug.h>
void ModelOpenGLObject::update(std::unique_ptr<ModelMesh> mesh) void ModelOpenGLObject::update(std::unique_ptr<ModelMesh> mesh)
{ {
@ -15,7 +15,7 @@ void ModelOpenGLObject::draw()
copyMeshToOpenGL(); copyMeshToOpenGL();
if (0 == m_meshTriangleVertexCount) if (0 == m_meshTriangleVertexCount)
return; return;
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions();
QOpenGLVertexArrayObject::Binder binder(&m_vertexArrayObject); QOpenGLVertexArrayObject::Binder binder(&m_vertexArrayObject);
f->glDrawArrays(GL_TRIANGLES, 0, m_meshTriangleVertexCount); f->glDrawArrays(GL_TRIANGLES, 0, m_meshTriangleVertexCount);
} }
@ -43,7 +43,7 @@ void ModelOpenGLObject::copyMeshToOpenGL()
m_buffer.bind(); m_buffer.bind();
m_buffer.allocate(mesh->triangleVertices(), mesh->triangleVertexCount() * sizeof(ModelOpenGLVertex)); m_buffer.allocate(mesh->triangleVertices(), mesh->triangleVertexCount() * sizeof(ModelOpenGLVertex));
m_meshTriangleVertexCount = mesh->triangleVertexCount(); m_meshTriangleVertexCount = mesh->triangleVertexCount();
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions();
f->glEnableVertexAttribArray(0); f->glEnableVertexAttribArray(0);
f->glEnableVertexAttribArray(1); f->glEnableVertexAttribArray(1);
f->glEnableVertexAttribArray(2); f->glEnableVertexAttribArray(2);
@ -53,13 +53,13 @@ void ModelOpenGLObject::copyMeshToOpenGL()
f->glEnableVertexAttribArray(6); f->glEnableVertexAttribArray(6);
f->glEnableVertexAttribArray(7); f->glEnableVertexAttribArray(7);
f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), 0); f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), 0);
f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast<void *>(3 * sizeof(GLfloat))); f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast<void*>(3 * sizeof(GLfloat)));
f->glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast<void *>(6 * sizeof(GLfloat))); f->glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast<void*>(6 * sizeof(GLfloat)));
f->glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast<void *>(9 * sizeof(GLfloat))); f->glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast<void*>(9 * sizeof(GLfloat)));
f->glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast<void *>(11 * sizeof(GLfloat))); f->glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast<void*>(11 * sizeof(GLfloat)));
f->glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast<void *>(12 * sizeof(GLfloat))); f->glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast<void*>(12 * sizeof(GLfloat)));
f->glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast<void *>(13 * sizeof(GLfloat))); f->glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast<void*>(13 * sizeof(GLfloat)));
f->glVertexAttribPointer(7, 1, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast<void *>(16 * sizeof(GLfloat))); f->glVertexAttribPointer(7, 1, GL_FLOAT, GL_FALSE, sizeof(ModelOpenGLVertex), reinterpret_cast<void*>(16 * sizeof(GLfloat)));
m_buffer.release(); m_buffer.release();
} }
} }

View File

@ -1,17 +1,17 @@
#ifndef DUST3D_APPLICATION_MODEL_OPENGL_OBJECT_H_ #ifndef DUST3D_APPLICATION_MODEL_OPENGL_OBJECT_H_
#define DUST3D_APPLICATION_MODEL_OPENGL_OBJECT_H_ #define DUST3D_APPLICATION_MODEL_OPENGL_OBJECT_H_
#include <memory>
#include <QMutex>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer>
#include "model_mesh.h" #include "model_mesh.h"
#include <QMutex>
#include <QOpenGLBuffer>
#include <QOpenGLVertexArrayObject>
#include <memory>
class ModelOpenGLObject class ModelOpenGLObject {
{
public: public:
void update(std::unique_ptr<ModelMesh> mesh); void update(std::unique_ptr<ModelMesh> mesh);
void draw(); void draw();
private: private:
void copyMeshToOpenGL(); void copyMeshToOpenGL();
QOpenGLVertexArrayObject m_vertexArrayObject; QOpenGLVertexArrayObject m_vertexArrayObject;

View File

@ -1,11 +1,11 @@
#include <QOpenGLFunctions>
#include <QFile>
#include <QMutexLocker>
#include <dust3d/base/debug.h>
#include "model_opengl_program.h" #include "model_opengl_program.h"
#include "dds_file.h" #include "dds_file.h"
#include <QFile>
#include <QMutexLocker>
#include <QOpenGLFunctions>
#include <dust3d/base/debug.h>
static const QString &loadShaderSource(const QString &name) static const QString& loadShaderSource(const QString& name)
{ {
static std::map<QString, QString> s_shaderSources; static std::map<QString, QString> s_shaderSources;
auto findShader = s_shaderSources.find(name); auto findShader = s_shaderSources.find(name);
@ -15,11 +15,11 @@ static const QString &loadShaderSource(const QString &name)
QFile file(name); QFile file(name);
file.open(QFile::ReadOnly | QFile::Text); file.open(QFile::ReadOnly | QFile::Text);
QTextStream stream(&file); QTextStream stream(&file);
auto insertResult = s_shaderSources.insert({name, stream.readAll()}); auto insertResult = s_shaderSources.insert({ name, stream.readAll() });
return insertResult.first->second; return insertResult.first->second;
} }
void ModelOpenGLProgram::addShaderFromResource(QOpenGLShader::ShaderType type, const char *resourceName) void ModelOpenGLProgram::addShaderFromResource(QOpenGLShader::ShaderType type, const char* resourceName)
{ {
if (!addShaderFromSourceCode(type, loadShaderSource(resourceName))) if (!addShaderFromSourceCode(type, loadShaderSource(resourceName)))
dust3dDebug << "Failed to addShaderFromResource, resource:" << resourceName << ", " << log().toStdString(); dust3dDebug << "Failed to addShaderFromResource, resource:" << resourceName << ", " << log().toStdString();
@ -57,7 +57,7 @@ void ModelOpenGLProgram::updateMetalnessRoughnessAmbientOcclusionMapImage(std::u
m_imageIsDirty = true; m_imageIsDirty = true;
} }
void ModelOpenGLProgram::activeAndBindTexture(int location, QOpenGLTexture *texture) void ModelOpenGLProgram::activeAndBindTexture(int location, QOpenGLTexture* texture)
{ {
if (0 == texture->textureId()) { if (0 == texture->textureId()) {
dust3dDebug << "Expected texture with a bound id"; dust3dDebug << "Expected texture with a bound id";
@ -105,7 +105,7 @@ void ModelOpenGLProgram::bindMaps()
DdsFileReader irradianceFile(":/resources/cedar_bridge_specular.dds"); DdsFileReader irradianceFile(":/resources/cedar_bridge_specular.dds");
m_environmentSpecularMap.reset(irradianceFile.createOpenGLTexture()); m_environmentSpecularMap.reset(irradianceFile.createOpenGLTexture());
} }
bindLocation++; bindLocation++;
activeAndBindTexture(bindLocation, m_environmentIrradianceMap.get()); activeAndBindTexture(bindLocation, m_environmentIrradianceMap.get());
setUniformValue(getUniformLocationByName("environmentIrradianceMapId"), bindLocation); setUniformValue(getUniformLocationByName("environmentIrradianceMapId"), bindLocation);
@ -224,12 +224,12 @@ void ModelOpenGLProgram::releaseMaps()
} }
} }
int ModelOpenGLProgram::getUniformLocationByName(const std::string &name) int ModelOpenGLProgram::getUniformLocationByName(const std::string& name)
{ {
auto findLocation = m_uniformLocationMap.find(name); auto findLocation = m_uniformLocationMap.find(name);
if (findLocation != m_uniformLocationMap.end()) if (findLocation != m_uniformLocationMap.end())
return findLocation->second; return findLocation->second;
int location = uniformLocation(name.c_str()); int location = uniformLocation(name.c_str());
m_uniformLocationMap.insert({name, location}); m_uniformLocationMap.insert({ name, location });
return location; return location;
} }

View File

@ -1,30 +1,29 @@
#ifndef DUST3D_APPLICATION_MODEL_OPENGL_PROGRAM_H_ #ifndef DUST3D_APPLICATION_MODEL_OPENGL_PROGRAM_H_
#define DUST3D_APPLICATION_MODEL_OPENGL_PROGRAM_H_ #define DUST3D_APPLICATION_MODEL_OPENGL_PROGRAM_H_
#include <memory>
#include <QOpenGLShaderProgram>
#include <QOpenGLShader>
#include <QOpenGLTexture>
#include <QMutex> #include <QMutex>
#include <QOpenGLShader>
#include <QOpenGLShaderProgram>
#include <QOpenGLTexture>
#include <memory>
class ModelOpenGLProgram: public QOpenGLShaderProgram class ModelOpenGLProgram : public QOpenGLShaderProgram {
{
public: public:
void load(bool isCoreProfile=false); void load(bool isCoreProfile = false);
int getUniformLocationByName(const std::string &name); int getUniformLocationByName(const std::string& name);
bool isCoreProfile() const; bool isCoreProfile() const;
void bindMaps(); void bindMaps();
void releaseMaps(); void releaseMaps();
void updateTextureImage(std::unique_ptr<QImage> image); void updateTextureImage(std::unique_ptr<QImage> image);
void updateNormalMapImage(std::unique_ptr<QImage> image); void updateNormalMapImage(std::unique_ptr<QImage> image);
void updateMetalnessRoughnessAmbientOcclusionMapImage(std::unique_ptr<QImage> image, void updateMetalnessRoughnessAmbientOcclusionMapImage(std::unique_ptr<QImage> image,
bool hasMetalnessMap = false, bool hasMetalnessMap = false,
bool hasRoughnessMap = false, bool hasRoughnessMap = false,
bool hasAmbientOcclusionMap = false); bool hasAmbientOcclusionMap = false);
private: private:
void addShaderFromResource(QOpenGLShader::ShaderType type, const char *resourceName); void addShaderFromResource(QOpenGLShader::ShaderType type, const char* resourceName);
void activeAndBindTexture(int location, QOpenGLTexture *texture); void activeAndBindTexture(int location, QOpenGLTexture* texture);
bool m_isLoaded = false; bool m_isLoaded = false;
bool m_isCoreProfile = false; bool m_isCoreProfile = false;

View File

@ -1,11 +1,11 @@
#include <QMouseEvent>
#include <QCoreApplication>
#include <QGuiApplication>
#include <cmath>
#include <QVector4D>
#include <QSurfaceFormat>
#include "model_widget.h" #include "model_widget.h"
#include "dds_file.h" #include "dds_file.h"
#include <QCoreApplication>
#include <QGuiApplication>
#include <QMouseEvent>
#include <QSurfaceFormat>
#include <QVector4D>
#include <cmath>
float ModelWidget::m_minZoomRatio = 5.0; float ModelWidget::m_minZoomRatio = 5.0;
float ModelWidget::m_maxZoomRatio = 80.0; float ModelWidget::m_maxZoomRatio = 80.0;
@ -18,36 +18,36 @@ QString ModelWidget::m_openGLVersion = "";
QString ModelWidget::m_openGLShadingLanguageVersion = ""; QString ModelWidget::m_openGLShadingLanguageVersion = "";
bool ModelWidget::m_openGLIsCoreProfile = false; bool ModelWidget::m_openGLIsCoreProfile = false;
ModelWidget::ModelWidget(QWidget *parent) : ModelWidget::ModelWidget(QWidget* parent)
QOpenGLWidget(parent) : QOpenGLWidget(parent)
{ {
setAttribute(Qt::WA_AlwaysStackOnTop); setAttribute(Qt::WA_AlwaysStackOnTop);
setAttribute(Qt::WA_TranslucentBackground); setAttribute(Qt::WA_TranslucentBackground);
QSurfaceFormat fmt = format(); QSurfaceFormat fmt = format();
fmt.setAlphaBufferSize(8); fmt.setAlphaBufferSize(8);
fmt.setSamples(4); fmt.setSamples(4);
setFormat(fmt); setFormat(fmt);
setContextMenuPolicy(Qt::CustomContextMenu); setContextMenuPolicy(Qt::CustomContextMenu);
m_widthInPixels = width() * window()->devicePixelRatio(); m_widthInPixels = width() * window()->devicePixelRatio();
m_heightInPixels = height() * window()->devicePixelRatio(); m_heightInPixels = height() * window()->devicePixelRatio();
zoom(200); zoom(200);
} }
const QVector3D &ModelWidget::eyePosition() const QVector3D& ModelWidget::eyePosition()
{ {
return m_eyePosition; return m_eyePosition;
} }
const QVector3D &ModelWidget::moveToPosition() const QVector3D& ModelWidget::moveToPosition()
{ {
return m_moveToPosition; return m_moveToPosition;
} }
void ModelWidget::setEyePosition(const QVector3D &eyePosition) void ModelWidget::setEyePosition(const QVector3D& eyePosition)
{ {
m_eyePosition = eyePosition; m_eyePosition = eyePosition;
emit eyePositionChanged(m_eyePosition); emit eyePositionChanged(m_eyePosition);
@ -130,7 +130,7 @@ void ModelWidget::disableCullFace()
m_enableCullFace = false; m_enableCullFace = false;
} }
void ModelWidget::setMoveToPosition(const QVector3D &moveToPosition) void ModelWidget::setMoveToPosition(const QVector3D& moveToPosition)
{ {
m_moveToPosition = moveToPosition; m_moveToPosition = moveToPosition;
} }
@ -144,13 +144,13 @@ void ModelWidget::updateProjectionMatrix()
void ModelWidget::resizeGL(int w, int h) void ModelWidget::resizeGL(int w, int h)
{ {
m_widthInPixels = w * window()->devicePixelRatio(); m_widthInPixels = w * window()->devicePixelRatio();
m_heightInPixels = h * window()->devicePixelRatio(); m_heightInPixels = h * window()->devicePixelRatio();
updateProjectionMatrix(); updateProjectionMatrix();
emit renderParametersChanged(); emit renderParametersChanged();
} }
std::pair<QVector3D, QVector3D> ModelWidget::screenPositionToMouseRay(const QPoint &screenPosition) std::pair<QVector3D, QVector3D> ModelWidget::screenPositionToMouseRay(const QPoint& screenPosition)
{ {
auto modelView = m_camera * m_world; auto modelView = m_camera * m_world;
float x = qMax(qMin(screenPosition.x(), width() - 1), 0); float x = qMax(qMin(screenPosition.x(), width() - 1), 0);
@ -190,12 +190,11 @@ void ModelWidget::toggleRotation()
} }
} }
bool ModelWidget::inputMousePressEventFromOtherWidget(QMouseEvent *event, bool notGraphics) bool ModelWidget::inputMousePressEventFromOtherWidget(QMouseEvent* event, bool notGraphics)
{ {
bool shouldStartMove = false; bool shouldStartMove = false;
if (event->button() == Qt::LeftButton) { if (event->button() == Qt::LeftButton) {
if ((notGraphics || QGuiApplication::queryKeyboardModifiers().testFlag(Qt::AltModifier)) && if ((notGraphics || QGuiApplication::queryKeyboardModifiers().testFlag(Qt::AltModifier)) && !QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ControlModifier)) {
!QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ControlModifier)) {
shouldStartMove = m_moveEnabled; shouldStartMove = m_moveEnabled;
} }
if (!shouldStartMove && !m_mousePickTargetPositionInModelSpace.isNull()) if (!shouldStartMove && !m_mousePickTargetPositionInModelSpace.isNull())
@ -216,7 +215,7 @@ bool ModelWidget::inputMousePressEventFromOtherWidget(QMouseEvent *event, bool n
return false; return false;
} }
bool ModelWidget::inputMouseReleaseEventFromOtherWidget(QMouseEvent *event) bool ModelWidget::inputMouseReleaseEventFromOtherWidget(QMouseEvent* event)
{ {
Q_UNUSED(event); Q_UNUSED(event);
if (m_moveStarted) { if (m_moveStarted) {
@ -235,10 +234,10 @@ void ModelWidget::canvasResized()
resize(parentWidget()->size()); resize(parentWidget()->size());
} }
bool ModelWidget::inputMouseMoveEventFromOtherWidget(QMouseEvent *event) bool ModelWidget::inputMouseMoveEventFromOtherWidget(QMouseEvent* event)
{ {
QPoint pos = convertInputPosFromOtherWidget(event); QPoint pos = convertInputPosFromOtherWidget(event);
if (m_mousePickingEnabled) { if (m_mousePickingEnabled) {
auto segment = screenPositionToMouseRay(pos); auto segment = screenPositionToMouseRay(pos);
emit mouseRayChanged(segment.first, segment.second); emit mouseRayChanged(segment.first, segment.second);
@ -247,12 +246,11 @@ bool ModelWidget::inputMouseMoveEventFromOtherWidget(QMouseEvent *event)
if (!m_moveStarted) { if (!m_moveStarted) {
return false; return false;
} }
int dx = pos.x() - m_lastPos.x(); int dx = pos.x() - m_lastPos.x();
int dy = pos.y() - m_lastPos.y(); int dy = pos.y() - m_lastPos.y();
if ((event->buttons() & Qt::MidButton) || if ((event->buttons() & Qt::MidButton) || (m_moveStarted && (event->buttons() & Qt::LeftButton))) {
(m_moveStarted && (event->buttons() & Qt::LeftButton))) {
if (QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ShiftModifier)) { if (QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ShiftModifier)) {
if (m_moveStarted) { if (m_moveStarted) {
if (m_moveAndZoomByWindow) { if (m_moveAndZoomByWindow) {
@ -283,27 +281,27 @@ bool ModelWidget::inputMouseMoveEventFromOtherWidget(QMouseEvent *event)
} }
} }
m_lastPos = pos; m_lastPos = pos;
return true; return true;
} }
QPoint ModelWidget::convertInputPosFromOtherWidget(QMouseEvent *event) QPoint ModelWidget::convertInputPosFromOtherWidget(QMouseEvent* event)
{ {
return mapFromGlobal(event->globalPos()); return mapFromGlobal(event->globalPos());
} }
bool ModelWidget::inputWheelEventFromOtherWidget(QWheelEvent *event) bool ModelWidget::inputWheelEventFromOtherWidget(QWheelEvent* event)
{ {
if (m_moveStarted) if (m_moveStarted)
return true; return true;
if (m_mousePickingEnabled) { if (m_mousePickingEnabled) {
if (QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ShiftModifier)) { if (QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ShiftModifier)) {
emit addMouseRadius((float)event->delta() / 200 / height()); emit addMouseRadius((float)event->delta() / 200 / height());
return true; return true;
} }
} }
if (!m_zoomEnabled) if (!m_zoomEnabled)
return false; return false;
@ -311,7 +309,7 @@ bool ModelWidget::inputWheelEventFromOtherWidget(QWheelEvent *event)
if (event->delta() < 0) if (event->delta() < 0)
delta = -delta; delta = -delta;
zoom(delta); zoom(delta);
return true; return true;
} }
@ -359,7 +357,7 @@ void ModelWidget::setMousePickRadius(float radius)
update(); update();
} }
void ModelWidget::updateMesh(ModelMesh *mesh) void ModelWidget::updateMesh(ModelMesh* mesh)
{ {
if (!m_modelOpenGLProgram) if (!m_modelOpenGLProgram)
m_modelOpenGLProgram = std::make_unique<ModelOpenGLProgram>(); m_modelOpenGLProgram = std::make_unique<ModelOpenGLProgram>();
@ -369,7 +367,7 @@ void ModelWidget::updateMesh(ModelMesh *mesh)
mesh && mesh->hasMetalnessInImage(), mesh && mesh->hasMetalnessInImage(),
mesh && mesh->hasRoughnessInImage(), mesh && mesh->hasRoughnessInImage(),
mesh && mesh->hasAmbientOcclusionInImage()); mesh && mesh->hasAmbientOcclusionInImage());
if (!m_modelOpenGLObject) if (!m_modelOpenGLObject)
m_modelOpenGLObject = std::make_unique<ModelOpenGLObject>(); m_modelOpenGLObject = std::make_unique<ModelOpenGLObject>();
m_modelOpenGLObject->update(std::unique_ptr<ModelMesh>(mesh)); m_modelOpenGLObject->update(std::unique_ptr<ModelMesh>(mesh));
@ -378,7 +376,7 @@ void ModelWidget::updateMesh(ModelMesh *mesh)
update(); update();
} }
void ModelWidget::updateWireframeMesh(MonochromeMesh *mesh) void ModelWidget::updateWireframeMesh(MonochromeMesh* mesh)
{ {
if (!m_wireframeOpenGLObject) if (!m_wireframeOpenGLObject)
m_wireframeOpenGLObject = std::make_unique<MonochromeOpenGLObject>(); m_wireframeOpenGLObject = std::make_unique<MonochromeOpenGLObject>();
@ -389,12 +387,12 @@ void ModelWidget::updateWireframeMesh(MonochromeMesh *mesh)
int ModelWidget::widthInPixels() int ModelWidget::widthInPixels()
{ {
return m_widthInPixels; return m_widthInPixels;
} }
int ModelWidget::heightInPixels() int ModelWidget::heightInPixels()
{ {
return m_heightInPixels; return m_heightInPixels;
} }
void ModelWidget::enableMove(bool enabled) void ModelWidget::enableMove(bool enabled)
@ -417,22 +415,22 @@ void ModelWidget::setMoveAndZoomByWindow(bool byWindow)
m_moveAndZoomByWindow = byWindow; m_moveAndZoomByWindow = byWindow;
} }
void ModelWidget::mousePressEvent(QMouseEvent *event) void ModelWidget::mousePressEvent(QMouseEvent* event)
{ {
inputMousePressEventFromOtherWidget(event, m_notGraphics); inputMousePressEventFromOtherWidget(event, m_notGraphics);
} }
void ModelWidget::mouseMoveEvent(QMouseEvent *event) void ModelWidget::mouseMoveEvent(QMouseEvent* event)
{ {
inputMouseMoveEventFromOtherWidget(event); inputMouseMoveEventFromOtherWidget(event);
} }
void ModelWidget::wheelEvent(QWheelEvent *event) void ModelWidget::wheelEvent(QWheelEvent* event)
{ {
inputWheelEventFromOtherWidget(event); inputWheelEventFromOtherWidget(event);
} }
void ModelWidget::mouseReleaseEvent(QMouseEvent *event) void ModelWidget::mouseReleaseEvent(QMouseEvent* event)
{ {
inputMouseReleaseEventFromOtherWidget(event); inputMouseReleaseEventFromOtherWidget(event);
} }
@ -442,7 +440,7 @@ void ModelWidget::setNotGraphics(bool notGraphics)
m_notGraphics = notGraphics; m_notGraphics = notGraphics;
} }
void ModelWidget::normalizeAngle(int &angle) void ModelWidget::normalizeAngle(int& angle)
{ {
while (angle < 0) while (angle < 0)
angle += 360 * 16; angle += 360 * 16;
@ -455,10 +453,10 @@ void ModelWidget::initializeGL()
connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &ModelWidget::cleanup); connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &ModelWidget::cleanup);
if (m_openGLVersion.isEmpty()) { if (m_openGLVersion.isEmpty()) {
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions();
const char *openGLVersion = (const char *)f->glGetString(GL_VERSION); const char* openGLVersion = (const char*)f->glGetString(GL_VERSION);
m_openGLVersion = nullptr != openGLVersion ? openGLVersion : "<Unknown>"; m_openGLVersion = nullptr != openGLVersion ? openGLVersion : "<Unknown>";
const char *shadingLanguageVersion = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION); const char* shadingLanguageVersion = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
m_openGLShadingLanguageVersion = nullptr != shadingLanguageVersion ? shadingLanguageVersion : "<Unknown>"; m_openGLShadingLanguageVersion = nullptr != shadingLanguageVersion ? shadingLanguageVersion : "<Unknown>";
m_openGLIsCoreProfile = QSurfaceFormat::defaultFormat().profile() == QSurfaceFormat::CoreProfile; m_openGLIsCoreProfile = QSurfaceFormat::defaultFormat().profile() == QSurfaceFormat::CoreProfile;
} }
@ -466,7 +464,7 @@ void ModelWidget::initializeGL()
void ModelWidget::paintGL() void ModelWidget::paintGL()
{ {
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions();
f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
f->glEnable(GL_BLEND); f->glEnable(GL_BLEND);
@ -485,13 +483,13 @@ void ModelWidget::paintGL()
f->glEnable(GL_POLYGON_OFFSET_FILL); f->glEnable(GL_POLYGON_OFFSET_FILL);
f->glPolygonOffset(1.0, 1.0); f->glPolygonOffset(1.0, 1.0);
f->glViewport(0, 0, m_widthInPixels, m_heightInPixels); f->glViewport(0, 0, m_widthInPixels, m_heightInPixels);
m_world.setToIdentity(); m_world.setToIdentity();
m_world.rotate(m_xRot / 16.0f, 1, 0, 0); m_world.rotate(m_xRot / 16.0f, 1, 0, 0);
m_world.rotate(m_yRot / 16.0f, 0, 1, 0); m_world.rotate(m_yRot / 16.0f, 0, 1, 0);
m_world.rotate(m_zRot / 16.0f, 0, 0, 1); m_world.rotate(m_zRot / 16.0f, 0, 0, 1);
m_camera.setToIdentity(); m_camera.setToIdentity();
m_camera.translate(m_eyePosition.x(), m_eyePosition.y(), m_eyePosition.z()); m_camera.translate(m_eyePosition.x(), m_eyePosition.y(), m_eyePosition.z());
@ -506,7 +504,7 @@ void ModelWidget::paintGL()
m_monochromeOpenGLProgram->load(format().profile() == QSurfaceFormat::CoreProfile); m_monochromeOpenGLProgram->load(format().profile() == QSurfaceFormat::CoreProfile);
} }
} }
drawModel(); drawModel();
if (m_isWireframeVisible) { if (m_isWireframeVisible) {
drawWireframe(); drawWireframe();

View File

@ -1,27 +1,26 @@
#ifndef DUST3D_APPLICATION_MODEL_WIDGET_H_ #ifndef DUST3D_APPLICATION_MODEL_WIDGET_H_
#define DUST3D_APPLICATION_MODEL_WIDGET_H_ #define DUST3D_APPLICATION_MODEL_WIDGET_H_
#include <memory> #include "model_mesh.h"
#include <QOpenGLWidget> #include "model_opengl_object.h"
#include <QOpenGLBuffer> #include "model_opengl_program.h"
#include <QOpenGLTexture> #include "monochrome_mesh.h"
#include "monochrome_opengl_object.h"
#include "monochrome_opengl_program.h"
#include <QMatrix4x4> #include <QMatrix4x4>
#include <QMutex> #include <QMutex>
#include <QVector2D> #include <QOpenGLBuffer>
#include <QTimer> #include <QOpenGLTexture>
#include <QOpenGLWidget>
#include <QString> #include <QString>
#include "model_mesh.h" #include <QTimer>
#include "model_opengl_program.h" #include <QVector2D>
#include "model_opengl_object.h" #include <memory>
#include "monochrome_mesh.h"
#include "monochrome_opengl_program.h"
#include "monochrome_opengl_object.h"
class ModelWidget : public QOpenGLWidget class ModelWidget : public QOpenGLWidget {
{
Q_OBJECT Q_OBJECT
signals: signals:
void mouseRayChanged(const QVector3D &near, const QVector3D &far); void mouseRayChanged(const QVector3D& near, const QVector3D& far);
void mousePressed(); void mousePressed();
void mouseReleased(); void mouseReleased();
void addMouseRadius(float radius); void addMouseRadius(float radius);
@ -29,13 +28,14 @@ signals:
void xRotationChanged(int angle); void xRotationChanged(int angle);
void yRotationChanged(int angle); void yRotationChanged(int angle);
void zRotationChanged(int angle); void zRotationChanged(int angle);
void eyePositionChanged(const QVector3D &eyePosition); void eyePositionChanged(const QVector3D& eyePosition);
void moveToPositionChanged(const QVector3D &moveToPosition); void moveToPositionChanged(const QVector3D& moveToPosition);
public: public:
ModelWidget(QWidget *parent = 0); ModelWidget(QWidget* parent = 0);
~ModelWidget(); ~ModelWidget();
void updateMesh(ModelMesh *mesh); void updateMesh(ModelMesh* mesh);
void updateWireframeMesh(MonochromeMesh *mesh); void updateWireframeMesh(MonochromeMesh* mesh);
void toggleWireframe(); void toggleWireframe();
bool isWireframeVisible(); bool isWireframeVisible();
void toggleRotation(); void toggleRotation();
@ -44,40 +44,42 @@ public:
void enableMousePicking(bool enabled); void enableMousePicking(bool enabled);
void setMoveAndZoomByWindow(bool byWindow); void setMoveAndZoomByWindow(bool byWindow);
void disableCullFace(); void disableCullFace();
void setMoveToPosition(const QVector3D &moveToPosition); void setMoveToPosition(const QVector3D& moveToPosition);
bool inputMousePressEventFromOtherWidget(QMouseEvent *event, bool notGraphics=false); bool inputMousePressEventFromOtherWidget(QMouseEvent* event, bool notGraphics = false);
bool inputMouseMoveEventFromOtherWidget(QMouseEvent *event); bool inputMouseMoveEventFromOtherWidget(QMouseEvent* event);
bool inputWheelEventFromOtherWidget(QWheelEvent *event); bool inputWheelEventFromOtherWidget(QWheelEvent* event);
bool inputMouseReleaseEventFromOtherWidget(QMouseEvent *event); bool inputMouseReleaseEventFromOtherWidget(QMouseEvent* event);
QPoint convertInputPosFromOtherWidget(QMouseEvent *event); QPoint convertInputPosFromOtherWidget(QMouseEvent* event);
int widthInPixels(); int widthInPixels();
int heightInPixels(); int heightInPixels();
void setNotGraphics(bool notGraphics); void setNotGraphics(bool notGraphics);
int xRot(); int xRot();
int yRot(); int yRot();
int zRot(); int zRot();
const QVector3D &eyePosition(); const QVector3D& eyePosition();
const QVector3D &moveToPosition(); const QVector3D& moveToPosition();
const QString &openGLVersion(); const QString& openGLVersion();
public slots: public slots:
void setXRotation(int angle); void setXRotation(int angle);
void setYRotation(int angle); void setYRotation(int angle);
void setZRotation(int angle); void setZRotation(int angle);
void setEyePosition(const QVector3D &eyePosition); void setEyePosition(const QVector3D& eyePosition);
void cleanup(); void cleanup();
void zoom(float delta); void zoom(float delta);
void setMousePickTargetPositionInModelSpace(QVector3D position); void setMousePickTargetPositionInModelSpace(QVector3D position);
void setMousePickRadius(float radius); void setMousePickRadius(float radius);
void reRender(); void reRender();
void canvasResized(); void canvasResized();
protected: protected:
void initializeGL() override; void initializeGL() override;
void paintGL() override; void paintGL() override;
void resizeGL(int width, int height) override; void resizeGL(int width, int height) override;
void mousePressEvent(QMouseEvent *event) override; void mousePressEvent(QMouseEvent* event) override;
void mouseMoveEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent* event) override;
void wheelEvent(QWheelEvent *event) override; void wheelEvent(QWheelEvent* event) override;
void mouseReleaseEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent* event) override;
private: private:
int m_xRot = m_defaultXRotation; int m_xRot = m_defaultXRotation;
int m_yRot = m_defaultYRotation; int m_yRot = m_defaultYRotation;
@ -103,7 +105,7 @@ private:
QPoint m_moveStartPos; QPoint m_moveStartPos;
QRect m_moveStartGeometry; QRect m_moveStartGeometry;
int m_modelInitialHeight = 0; int m_modelInitialHeight = 0;
QTimer *m_rotationTimer = nullptr; QTimer* m_rotationTimer = nullptr;
int m_widthInPixels = 0; int m_widthInPixels = 0;
int m_heightInPixels = 0; int m_heightInPixels = 0;
QVector3D m_moveToPosition; QVector3D m_moveToPosition;
@ -111,11 +113,12 @@ private:
bool m_enableCullFace = true; bool m_enableCullFace = true;
bool m_notGraphics = false; bool m_notGraphics = false;
bool m_isWireframeVisible = false; bool m_isWireframeVisible = false;
std::pair<QVector3D, QVector3D> screenPositionToMouseRay(const QPoint &screenPosition); std::pair<QVector3D, QVector3D> screenPositionToMouseRay(const QPoint& screenPosition);
void updateProjectionMatrix(); void updateProjectionMatrix();
void normalizeAngle(int &angle); void normalizeAngle(int& angle);
void drawModel(); void drawModel();
void drawWireframe(); void drawWireframe();
public: public:
static int m_defaultXRotation; static int m_defaultXRotation;
static int m_defaultYRotation; static int m_defaultYRotation;

View File

@ -1,59 +1,57 @@
#include <set>
#include "monochrome_mesh.h" #include "monochrome_mesh.h"
#include <set>
MonochromeMesh::MonochromeMesh(const MonochromeMesh &mesh) MonochromeMesh::MonochromeMesh(const MonochromeMesh& mesh)
{ {
m_lineVertices = mesh.m_lineVertices; m_lineVertices = mesh.m_lineVertices;
} }
MonochromeMesh::MonochromeMesh(MonochromeMesh &&mesh) MonochromeMesh::MonochromeMesh(MonochromeMesh&& mesh)
{ {
m_lineVertices = std::move(mesh.m_lineVertices); m_lineVertices = std::move(mesh.m_lineVertices);
} }
MonochromeMesh::MonochromeMesh(const dust3d::Object &object) MonochromeMesh::MonochromeMesh(const dust3d::Object& object)
{ {
std::set<std::pair<size_t, size_t>> halfEdges; std::set<std::pair<size_t, size_t>> halfEdges;
for (const auto &face: object.triangleAndQuads) { for (const auto& face : object.triangleAndQuads) {
if (3 == face.size()) { if (3 == face.size()) {
halfEdges.insert({face[0], face[1]}); halfEdges.insert({ face[0], face[1] });
halfEdges.insert({face[1], face[0]}); halfEdges.insert({ face[1], face[0] });
halfEdges.insert({face[1], face[2]}); halfEdges.insert({ face[1], face[2] });
halfEdges.insert({face[2], face[1]}); halfEdges.insert({ face[2], face[1] });
halfEdges.insert({face[2], face[0]}); halfEdges.insert({ face[2], face[0] });
halfEdges.insert({face[0], face[2]}); halfEdges.insert({ face[0], face[2] });
continue; continue;
} }
halfEdges.insert({face[0], face[1]}); halfEdges.insert({ face[0], face[1] });
halfEdges.insert({face[1], face[0]}); halfEdges.insert({ face[1], face[0] });
halfEdges.insert({face[1], face[2]}); halfEdges.insert({ face[1], face[2] });
halfEdges.insert({face[2], face[1]}); halfEdges.insert({ face[2], face[1] });
halfEdges.insert({face[2], face[3]}); halfEdges.insert({ face[2], face[3] });
halfEdges.insert({face[3], face[2]}); halfEdges.insert({ face[3], face[2] });
halfEdges.insert({face[3], face[0]}); halfEdges.insert({ face[3], face[0] });
halfEdges.insert({face[0], face[3]}); halfEdges.insert({ face[0], face[3] });
} }
m_lineVertices.reserve(halfEdges.size() * 2); m_lineVertices.reserve(halfEdges.size() * 2);
for (const auto &halfEdge: halfEdges) { for (const auto& halfEdge : halfEdges) {
// For two halfedges shared one edge, only output one line // For two halfedges shared one edge, only output one line
if (halfEdge.first > halfEdge.second) if (halfEdge.first > halfEdge.second)
continue; continue;
const auto &from = object.vertices[halfEdge.first]; const auto& from = object.vertices[halfEdge.first];
const auto &to = object.vertices[halfEdge.second]; const auto& to = object.vertices[halfEdge.second];
m_lineVertices.emplace_back(MonochromeOpenGLVertex { m_lineVertices.emplace_back(MonochromeOpenGLVertex {
(GLfloat)from.x(), (GLfloat)from.x(),
(GLfloat)from.y(), (GLfloat)from.y(),
(GLfloat)from.z() (GLfloat)from.z() });
});
m_lineVertices.emplace_back(MonochromeOpenGLVertex { m_lineVertices.emplace_back(MonochromeOpenGLVertex {
(GLfloat)to.x(), (GLfloat)to.x(),
(GLfloat)to.y(), (GLfloat)to.y(),
(GLfloat)to.z() (GLfloat)to.z() });
});
} }
} }
const MonochromeOpenGLVertex *MonochromeMesh::lineVertices() const MonochromeOpenGLVertex* MonochromeMesh::lineVertices()
{ {
if (m_lineVertices.empty()) if (m_lineVertices.empty())
return nullptr; return nullptr;

View File

@ -1,21 +1,20 @@
#ifndef DUST3D_APPLICATION_MONOCHROME_MESH_H_ #ifndef DUST3D_APPLICATION_MONOCHROME_MESH_H_
#define DUST3D_APPLICATION_MONOCHROME_MESH_H_ #define DUST3D_APPLICATION_MONOCHROME_MESH_H_
#include <memory>
#include <dust3d/base/object.h>
#include "monochrome_opengl_vertex.h" #include "monochrome_opengl_vertex.h"
#include <dust3d/base/object.h>
#include <memory>
class MonochromeMesh class MonochromeMesh {
{
public: public:
MonochromeMesh(const MonochromeMesh &mesh); MonochromeMesh(const MonochromeMesh& mesh);
MonochromeMesh(MonochromeMesh &&mesh); MonochromeMesh(MonochromeMesh&& mesh);
MonochromeMesh(const dust3d::Object &object); MonochromeMesh(const dust3d::Object& object);
const MonochromeOpenGLVertex *lineVertices(); const MonochromeOpenGLVertex* lineVertices();
int lineVertexCount(); int lineVertexCount();
private: private:
std::vector<MonochromeOpenGLVertex> m_lineVertices; std::vector<MonochromeOpenGLVertex> m_lineVertices;
}; };
#endif #endif

View File

@ -1,7 +1,7 @@
#include <dust3d/base/debug.h>
#include <QOpenGLFunctions>
#include <QOpenGLContext>
#include "monochrome_opengl_object.h" #include "monochrome_opengl_object.h"
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <dust3d/base/debug.h>
void MonochromeOpenGLObject::update(std::unique_ptr<MonochromeMesh> mesh) void MonochromeOpenGLObject::update(std::unique_ptr<MonochromeMesh> mesh)
{ {
@ -15,7 +15,7 @@ void MonochromeOpenGLObject::draw()
copyMeshToOpenGL(); copyMeshToOpenGL();
if (0 == m_meshLineVertexCount) if (0 == m_meshLineVertexCount)
return; return;
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions();
QOpenGLVertexArrayObject::Binder binder(&m_vertexArrayObject); QOpenGLVertexArrayObject::Binder binder(&m_vertexArrayObject);
f->glDrawArrays(GL_LINES, 0, m_meshLineVertexCount); f->glDrawArrays(GL_LINES, 0, m_meshLineVertexCount);
} }
@ -43,13 +43,13 @@ void MonochromeOpenGLObject::copyMeshToOpenGL()
m_buffer.bind(); m_buffer.bind();
m_buffer.allocate(mesh->lineVertices(), mesh->lineVertexCount() * sizeof(MonochromeOpenGLVertex)); m_buffer.allocate(mesh->lineVertices(), mesh->lineVertexCount() * sizeof(MonochromeOpenGLVertex));
m_meshLineVertexCount = mesh->lineVertexCount(); m_meshLineVertexCount = mesh->lineVertexCount();
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions();
f->glEnableVertexAttribArray(0); f->glEnableVertexAttribArray(0);
f->glEnableVertexAttribArray(1); f->glEnableVertexAttribArray(1);
f->glEnableVertexAttribArray(2); f->glEnableVertexAttribArray(2);
f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(MonochromeOpenGLVertex), 0); f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(MonochromeOpenGLVertex), 0);
f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(MonochromeOpenGLVertex), reinterpret_cast<void *>(3 * sizeof(GLfloat))); f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(MonochromeOpenGLVertex), reinterpret_cast<void*>(3 * sizeof(GLfloat)));
f->glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(MonochromeOpenGLVertex), reinterpret_cast<void *>(6 * sizeof(GLfloat))); f->glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(MonochromeOpenGLVertex), reinterpret_cast<void*>(6 * sizeof(GLfloat)));
m_buffer.release(); m_buffer.release();
} }
} }

View File

@ -1,17 +1,17 @@
#ifndef DUST3D_APPLICATION_MONOCHROME_OPENGL_OBJECT_H_ #ifndef DUST3D_APPLICATION_MONOCHROME_OPENGL_OBJECT_H_
#define DUST3D_APPLICATION_MONOCHROME_OPENGL_OBJECT_H_ #define DUST3D_APPLICATION_MONOCHROME_OPENGL_OBJECT_H_
#include <memory>
#include <QMutex>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer>
#include "monochrome_mesh.h" #include "monochrome_mesh.h"
#include <QMutex>
#include <QOpenGLBuffer>
#include <QOpenGLVertexArrayObject>
#include <memory>
class MonochromeOpenGLObject class MonochromeOpenGLObject {
{
public: public:
void update(std::unique_ptr<MonochromeMesh> mesh); void update(std::unique_ptr<MonochromeMesh> mesh);
void draw(); void draw();
private: private:
void copyMeshToOpenGL(); void copyMeshToOpenGL();
QOpenGLVertexArrayObject m_vertexArrayObject; QOpenGLVertexArrayObject m_vertexArrayObject;

View File

@ -1,9 +1,9 @@
#include <QOpenGLFunctions>
#include <QFile>
#include <dust3d/base/debug.h>
#include "monochrome_opengl_program.h" #include "monochrome_opengl_program.h"
#include <QFile>
#include <QOpenGLFunctions>
#include <dust3d/base/debug.h>
static const QString &loadShaderSource(const QString &name) static const QString& loadShaderSource(const QString& name)
{ {
static std::map<QString, QString> s_shaderSources; static std::map<QString, QString> s_shaderSources;
auto findShader = s_shaderSources.find(name); auto findShader = s_shaderSources.find(name);
@ -13,11 +13,11 @@ static const QString &loadShaderSource(const QString &name)
QFile file(name); QFile file(name);
file.open(QFile::ReadOnly | QFile::Text); file.open(QFile::ReadOnly | QFile::Text);
QTextStream stream(&file); QTextStream stream(&file);
auto insertResult = s_shaderSources.insert({name, stream.readAll()}); auto insertResult = s_shaderSources.insert({ name, stream.readAll() });
return insertResult.first->second; return insertResult.first->second;
} }
void MonochromeOpenGLProgram::addShaderFromResource(QOpenGLShader::ShaderType type, const char *resourceName) void MonochromeOpenGLProgram::addShaderFromResource(QOpenGLShader::ShaderType type, const char* resourceName)
{ {
if (!addShaderFromSourceCode(type, loadShaderSource(resourceName))) if (!addShaderFromSourceCode(type, loadShaderSource(resourceName)))
dust3dDebug << "Failed to addShaderFromResource, resource:" << resourceName << ", " << log().toStdString(); dust3dDebug << "Failed to addShaderFromResource, resource:" << resourceName << ", " << log().toStdString();
@ -49,12 +49,12 @@ void MonochromeOpenGLProgram::load(bool isCoreProfile)
m_isLoaded = true; m_isLoaded = true;
} }
int MonochromeOpenGLProgram::getUniformLocationByName(const std::string &name) int MonochromeOpenGLProgram::getUniformLocationByName(const std::string& name)
{ {
auto findLocation = m_uniformLocationMap.find(name); auto findLocation = m_uniformLocationMap.find(name);
if (findLocation != m_uniformLocationMap.end()) if (findLocation != m_uniformLocationMap.end())
return findLocation->second; return findLocation->second;
int location = uniformLocation(name.c_str()); int location = uniformLocation(name.c_str());
m_uniformLocationMap.insert({name, location}); m_uniformLocationMap.insert({ name, location });
return location; return location;
} }

View File

@ -1,19 +1,18 @@
#ifndef DUST3D_APPLICATION_MONOCHROME_OPENGL_PROGRAM_H_ #ifndef DUST3D_APPLICATION_MONOCHROME_OPENGL_PROGRAM_H_
#define DUST3D_APPLICATION_MONOCHROME_OPENGL_PROGRAM_H_ #define DUST3D_APPLICATION_MONOCHROME_OPENGL_PROGRAM_H_
#include <memory>
#include <QOpenGLShaderProgram>
#include <QOpenGLShader> #include <QOpenGLShader>
#include <QOpenGLShaderProgram>
#include <memory>
class MonochromeOpenGLProgram: public QOpenGLShaderProgram class MonochromeOpenGLProgram : public QOpenGLShaderProgram {
{
public: public:
void load(bool isCoreProfile=false); void load(bool isCoreProfile = false);
int getUniformLocationByName(const std::string &name); int getUniformLocationByName(const std::string& name);
bool isCoreProfile() const; bool isCoreProfile() const;
private: private:
void addShaderFromResource(QOpenGLShader::ShaderType type, const char *resourceName); void addShaderFromResource(QOpenGLShader::ShaderType type, const char* resourceName);
bool m_isLoaded = false; bool m_isLoaded = false;
bool m_isCoreProfile = false; bool m_isCoreProfile = false;

View File

@ -1,27 +1,27 @@
#include <QVBoxLayout>
#include <QWidgetAction>
#include <QMenu>
#include "part_manage_widget.h" #include "part_manage_widget.h"
#include "component_list_model.h"
#include "component_preview_grid_widget.h" #include "component_preview_grid_widget.h"
#include "component_property_widget.h" #include "component_property_widget.h"
#include "component_list_model.h"
#include "theme.h"
#include "document.h" #include "document.h"
#include "theme.h"
#include <QMenu>
#include <QVBoxLayout>
#include <QWidgetAction>
PartManageWidget::PartManageWidget(Document *document, QWidget *parent): PartManageWidget::PartManageWidget(Document* document, QWidget* parent)
QWidget(parent), : QWidget(parent)
m_document(document) , m_document(document)
{ {
setContextMenuPolicy(Qt::CustomContextMenu); setContextMenuPolicy(Qt::CustomContextMenu);
QHBoxLayout *toolsLayout = new QHBoxLayout; QHBoxLayout* toolsLayout = new QHBoxLayout;
toolsLayout->setSpacing(0); toolsLayout->setSpacing(0);
toolsLayout->setMargin(0); toolsLayout->setMargin(0);
setStyleSheet("QPushButton:disabled {border: 0; color: " + Theme::gray.name() + "}"); setStyleSheet("QPushButton:disabled {border: 0; color: " + Theme::gray.name() + "}");
auto createButton = [](QChar icon, const QString &title) { auto createButton = [](QChar icon, const QString& title) {
QPushButton *button = new QPushButton(icon); QPushButton* button = new QPushButton(icon);
Theme::initIconButton(button); Theme::initIconButton(button);
button->setToolTip(title); button->setToolTip(title);
return button; return button;
@ -58,50 +58,50 @@ PartManageWidget::PartManageWidget(Document *document, QWidget *parent):
//connect(m_componentPreviewGridWidget->selectionModel(), &QItemSelectionModel::selectionChanged, this, &PartManageWidget::showSelectedComponentProperties); //connect(m_componentPreviewGridWidget->selectionModel(), &QItemSelectionModel::selectionChanged, this, &PartManageWidget::showSelectedComponentProperties);
connect(m_levelUpButton, &QPushButton::clicked, [this]() { connect(m_levelUpButton, &QPushButton::clicked, [this]() {
const auto &parent = m_document->findComponentParent(this->m_componentPreviewGridWidget->componentListModel()->listingComponentId()); const auto& parent = m_document->findComponentParent(this->m_componentPreviewGridWidget->componentListModel()->listingComponentId());
if (nullptr == parent) if (nullptr == parent)
return; return;
this->m_componentPreviewGridWidget->componentListModel()->setListingComponentId(parent->id); this->m_componentPreviewGridWidget->componentListModel()->setListingComponentId(parent->id);
}); });
connect(m_hideButton, &QPushButton::clicked, [this]() { connect(m_hideButton, &QPushButton::clicked, [this]() {
for (const auto &partId: this->m_componentPreviewGridWidget->getSelectedPartIds()) for (const auto& partId : this->m_componentPreviewGridWidget->getSelectedPartIds())
this->m_document->setPartVisibleState(partId, false); this->m_document->setPartVisibleState(partId, false);
this->m_document->saveSnapshot(); this->m_document->saveSnapshot();
}); });
connect(m_showButton, &QPushButton::clicked, [this]() { connect(m_showButton, &QPushButton::clicked, [this]() {
for (const auto &partId: this->m_componentPreviewGridWidget->getSelectedPartIds()) for (const auto& partId : this->m_componentPreviewGridWidget->getSelectedPartIds())
this->m_document->setPartVisibleState(partId, true); this->m_document->setPartVisibleState(partId, true);
this->m_document->saveSnapshot(); this->m_document->saveSnapshot();
}); });
connect(m_unlockButton, &QPushButton::clicked, [this]() { connect(m_unlockButton, &QPushButton::clicked, [this]() {
for (const auto &partId: this->m_componentPreviewGridWidget->getSelectedPartIds()) for (const auto& partId : this->m_componentPreviewGridWidget->getSelectedPartIds())
this->m_document->setPartLockState(partId, false); this->m_document->setPartLockState(partId, false);
this->m_document->saveSnapshot(); this->m_document->saveSnapshot();
}); });
connect(m_lockButton, &QPushButton::clicked, [this]() { connect(m_lockButton, &QPushButton::clicked, [this]() {
for (const auto &partId: this->m_componentPreviewGridWidget->getSelectedPartIds()) for (const auto& partId : this->m_componentPreviewGridWidget->getSelectedPartIds())
this->m_document->setPartLockState(partId, true); this->m_document->setPartLockState(partId, true);
this->m_document->saveSnapshot(); this->m_document->saveSnapshot();
}); });
connect(m_unlinkButton, &QPushButton::clicked, [this]() { connect(m_unlinkButton, &QPushButton::clicked, [this]() {
for (const auto &partId: this->m_componentPreviewGridWidget->getSelectedPartIds()) for (const auto& partId : this->m_componentPreviewGridWidget->getSelectedPartIds())
this->m_document->setPartDisableState(partId, true); this->m_document->setPartDisableState(partId, true);
this->m_document->saveSnapshot(); this->m_document->saveSnapshot();
}); });
connect(m_linkButton, &QPushButton::clicked, [this]() { connect(m_linkButton, &QPushButton::clicked, [this]() {
for (const auto &partId: this->m_componentPreviewGridWidget->getSelectedPartIds()) for (const auto& partId : this->m_componentPreviewGridWidget->getSelectedPartIds())
this->m_document->setPartDisableState(partId, false); this->m_document->setPartDisableState(partId, false);
this->m_document->saveSnapshot(); this->m_document->saveSnapshot();
}); });
connect(m_selectButton, &QPushButton::clicked, [this]() { connect(m_selectButton, &QPushButton::clicked, [this]() {
for (const auto &componentId: this->m_componentPreviewGridWidget->getSelectedComponentIds()) { for (const auto& componentId : this->m_componentPreviewGridWidget->getSelectedComponentIds()) {
std::vector<dust3d::Uuid> partIds; std::vector<dust3d::Uuid> partIds;
this->m_document->collectComponentDescendantParts(componentId, partIds); this->m_document->collectComponentDescendantParts(componentId, partIds);
for (const auto &partId: partIds) for (const auto& partId : partIds)
emit this->selectPartOnCanvas(partId); emit this->selectPartOnCanvas(partId);
} }
}); });
@ -119,7 +119,7 @@ PartManageWidget::PartManageWidget(Document *document, QWidget *parent):
connect(this, &PartManageWidget::customContextMenuRequested, this, &PartManageWidget::showContextMenu); connect(this, &PartManageWidget::customContextMenuRequested, this, &PartManageWidget::showContextMenu);
QVBoxLayout *mainLayout = new QVBoxLayout; QVBoxLayout* mainLayout = new QVBoxLayout;
mainLayout->addLayout(toolsLayout); mainLayout->addLayout(toolsLayout);
mainLayout->addWidget(m_componentPreviewGridWidget); mainLayout->addWidget(m_componentPreviewGridWidget);
@ -135,10 +135,10 @@ void PartManageWidget::showSelectedComponentProperties()
if (componentIds.empty()) if (componentIds.empty())
return; return;
auto *propertyWidget = new ComponentPropertyWidget(m_document, componentIds); auto* propertyWidget = new ComponentPropertyWidget(m_document, componentIds);
auto menu = std::make_unique<QMenu>(this->parentWidget()); auto menu = std::make_unique<QMenu>(this->parentWidget());
QWidgetAction *widgetAction = new QWidgetAction(menu.get()); QWidgetAction* widgetAction = new QWidgetAction(menu.get());
widgetAction->setDefaultWidget(propertyWidget); widgetAction->setDefaultWidget(propertyWidget);
menu->addAction(widgetAction); menu->addAction(widgetAction);
@ -146,14 +146,13 @@ void PartManageWidget::showSelectedComponentProperties()
if (x <= 0) if (x <= 0)
x = QCursor::pos().x(); x = QCursor::pos().x();
menu->exec(QPoint( menu->exec(QPoint(
x - propertyWidget->width(), x - propertyWidget->width(),
QCursor::pos().y() QCursor::pos().y()));
));
} }
void PartManageWidget::selectComponentByPartId(const dust3d::Uuid &partId) void PartManageWidget::selectComponentByPartId(const dust3d::Uuid& partId)
{ {
const auto &part = m_document->findPart(partId); const auto& part = m_document->findPart(partId);
if (nullptr == part) if (nullptr == part)
return; return;
auto componentId = part->componentId; auto componentId = part->componentId;
@ -163,7 +162,7 @@ void PartManageWidget::selectComponentByPartId(const dust3d::Uuid &partId)
m_componentPreviewGridWidget->scrollTo(index); m_componentPreviewGridWidget->scrollTo(index);
return; return;
} }
const auto &component = m_document->findComponent(componentId); const auto& component = m_document->findComponent(componentId);
if (nullptr == component) if (nullptr == component)
return; return;
m_componentPreviewGridWidget->componentListModel()->setListingComponentId(component->parentId); m_componentPreviewGridWidget->componentListModel()->setListingComponentId(component->parentId);
@ -178,7 +177,7 @@ void PartManageWidget::selectComponentByPartId(const dust3d::Uuid &partId)
void PartManageWidget::updateLevelUpButton() void PartManageWidget::updateLevelUpButton()
{ {
const auto &parent = m_document->findComponentParent(m_componentPreviewGridWidget->componentListModel()->listingComponentId()); const auto& parent = m_document->findComponentParent(m_componentPreviewGridWidget->componentListModel()->listingComponentId());
m_levelUpButton->setEnabled(nullptr != parent); m_levelUpButton->setEnabled(nullptr != parent);
} }
@ -193,13 +192,13 @@ void PartManageWidget::updateToolButtons()
bool enableUnlinkButton = false; bool enableUnlinkButton = false;
bool enableLinkButton = false; bool enableLinkButton = false;
bool enablePropertyButton = false; bool enablePropertyButton = false;
for (const auto &component: selectedComponents) { for (const auto& component : selectedComponents) {
enablePropertyButton = true; enablePropertyButton = true;
enableSelectButton = true; enableSelectButton = true;
if (component->linkToPartId.isNull()) { if (component->linkToPartId.isNull()) {
continue; continue;
} }
const auto &part = m_document->findPart(component->linkToPartId); const auto& part = m_document->findPart(component->linkToPartId);
if (part->visible) { if (part->visible) {
enableHideButton = true; enableHideButton = true;
} else { } else {
@ -229,14 +228,14 @@ void PartManageWidget::updateToolButtons()
bool PartManageWidget::hasSelectedGroupedComponent() bool PartManageWidget::hasSelectedGroupedComponent()
{ {
auto selectedComponents = m_componentPreviewGridWidget->getSelectedComponents(); auto selectedComponents = m_componentPreviewGridWidget->getSelectedComponents();
for (auto &component: selectedComponents) { for (auto& component : selectedComponents) {
if (!component->childrenIds.empty()) if (!component->childrenIds.empty())
return true; return true;
} }
return false; return false;
} }
void PartManageWidget::showContextMenu(const QPoint &pos) void PartManageWidget::showContextMenu(const QPoint& pos)
{ {
auto selectedComponentIds = m_componentPreviewGridWidget->getSelectedComponentIds(); auto selectedComponentIds = m_componentPreviewGridWidget->getSelectedComponentIds();
if (selectedComponentIds.empty()) if (selectedComponentIds.empty())
@ -255,7 +254,7 @@ void PartManageWidget::showContextMenu(const QPoint &pos)
QAction ungroupAction(tr("Ungroup"), this); QAction ungroupAction(tr("Ungroup"), this);
if (hasSelectedGroupedComponent()) { if (hasSelectedGroupedComponent()) {
connect(&ungroupAction, &QAction::triggered, this, [=]() { connect(&ungroupAction, &QAction::triggered, this, [=]() {
for (const auto &it: selectedComponentIds) for (const auto& it : selectedComponentIds)
emit this->ungroupComponent(it); emit this->ungroupComponent(it);
emit this->groupOperationAdded(); emit this->groupOperationAdded();
}); });

View File

@ -1,41 +1,42 @@
#ifndef DUST3D_APPLICATION_PART_MANAGE_WIDGET_H_ #ifndef DUST3D_APPLICATION_PART_MANAGE_WIDGET_H_
#define DUST3D_APPLICATION_PART_MANAGE_WIDGET_H_ #define DUST3D_APPLICATION_PART_MANAGE_WIDGET_H_
#include <dust3d/base/uuid.h>
#include <QWidget> #include <QWidget>
#include <dust3d/base/uuid.h>
class Document; class Document;
class ComponentPreviewGridWidget; class ComponentPreviewGridWidget;
class ComponentPropertyWidget; class ComponentPropertyWidget;
class QPushButton; class QPushButton;
class PartManageWidget: public QWidget class PartManageWidget : public QWidget {
{
Q_OBJECT Q_OBJECT
signals: signals:
void unselectAllOnCanvas(); void unselectAllOnCanvas();
void selectPartOnCanvas(const dust3d::Uuid &partId); void selectPartOnCanvas(const dust3d::Uuid& partId);
void groupComponents(const std::vector<dust3d::Uuid> &componentIds); void groupComponents(const std::vector<dust3d::Uuid>& componentIds);
void ungroupComponent(const dust3d::Uuid &componentId); void ungroupComponent(const dust3d::Uuid& componentId);
void groupOperationAdded(); void groupOperationAdded();
public slots: public slots:
void selectComponentByPartId(const dust3d::Uuid &partId); void selectComponentByPartId(const dust3d::Uuid& partId);
void showSelectedComponentProperties(); void showSelectedComponentProperties();
void showContextMenu(const QPoint &pos); void showContextMenu(const QPoint& pos);
public: public:
PartManageWidget(Document *document, QWidget *parent=nullptr); PartManageWidget(Document* document, QWidget* parent = nullptr);
private: private:
Document *m_document = nullptr; Document* m_document = nullptr;
ComponentPreviewGridWidget *m_componentPreviewGridWidget = nullptr; ComponentPreviewGridWidget* m_componentPreviewGridWidget = nullptr;
QPushButton *m_levelUpButton = nullptr; QPushButton* m_levelUpButton = nullptr;
QPushButton *m_selectButton = nullptr; QPushButton* m_selectButton = nullptr;
QPushButton *m_lockButton = nullptr; QPushButton* m_lockButton = nullptr;
QPushButton *m_unlockButton = nullptr; QPushButton* m_unlockButton = nullptr;
QPushButton *m_showButton = nullptr; QPushButton* m_showButton = nullptr;
QPushButton *m_hideButton = nullptr; QPushButton* m_hideButton = nullptr;
QPushButton *m_unlinkButton = nullptr; QPushButton* m_unlinkButton = nullptr;
QPushButton *m_linkButton = nullptr; QPushButton* m_linkButton = nullptr;
QPushButton *m_propertyButton = nullptr; QPushButton* m_propertyButton = nullptr;
void updateToolButtons(); void updateToolButtons();
void updateLevelUpButton(); void updateLevelUpButton();
bool hasSelectedGroupedComponent(); bool hasSelectedGroupedComponent();

View File

@ -1,10 +1,10 @@
#include "preferences.h" #include "preferences.h"
#define MAX_RECENT_FILES 7 #define MAX_RECENT_FILES 7
Preferences &Preferences::instance() Preferences& Preferences::instance()
{ {
static Preferences *s_preferences = nullptr; static Preferences* s_preferences = nullptr;
if (nullptr == s_preferences) { if (nullptr == s_preferences) {
s_preferences = new Preferences; s_preferences = new Preferences;
} }
@ -40,15 +40,15 @@ int Preferences::maxRecentFiles() const
return MAX_RECENT_FILES; return MAX_RECENT_FILES;
} }
void Preferences::setCurrentFile(const QString &fileName) void Preferences::setCurrentFile(const QString& fileName)
{ {
QStringList files = m_settings.value("recentFileList").toStringList(); QStringList files = m_settings.value("recentFileList").toStringList();
files.removeAll(fileName); files.removeAll(fileName);
files.prepend(fileName); files.prepend(fileName);
while (files.size() > MAX_RECENT_FILES) while (files.size() > MAX_RECENT_FILES)
files.removeLast(); files.removeLast();
m_settings.setValue("recentFileList", files); m_settings.setValue("recentFileList", files);
} }
@ -57,6 +57,6 @@ void Preferences::reset()
auto files = m_settings.value("recentFileList").toStringList(); auto files = m_settings.value("recentFileList").toStringList();
m_settings.clear(); m_settings.clear();
m_settings.setValue("recentFileList", files); m_settings.setValue("recentFileList", files);
loadDefault(); loadDefault();
} }

View File

@ -5,19 +5,19 @@
#include <QSize> #include <QSize>
#include <QStringList> #include <QStringList>
class Preferences : public QObject class Preferences : public QObject {
{
Q_OBJECT Q_OBJECT
public: public:
static Preferences &instance(); static Preferences& instance();
Preferences(); Preferences();
QSize documentWindowSize() const; QSize documentWindowSize() const;
void setDocumentWindowSize(const QSize&); void setDocumentWindowSize(const QSize&);
QStringList recentFileList() const; QStringList recentFileList() const;
int maxRecentFiles() const; int maxRecentFiles() const;
public slots: public slots:
void setCurrentFile(const QString &fileName); void setCurrentFile(const QString& fileName);
void reset(); void reset();
private: private:
QSettings m_settings; QSettings m_settings;
void loadDefault(); void loadDefault();

View File

@ -1,8 +1,8 @@
#include "preview_grid_view.h" #include "preview_grid_view.h"
#include "theme.h" #include "theme.h"
PreviewGridView::PreviewGridView(QWidget *parent): PreviewGridView::PreviewGridView(QWidget* parent)
QListView(parent) : QListView(parent)
{ {
QPalette viewPalette = palette(); QPalette viewPalette = palette();
viewPalette.setColor(QPalette::Window, Qt::transparent); viewPalette.setColor(QPalette::Window, Qt::transparent);
@ -13,9 +13,7 @@ PreviewGridView::PreviewGridView(QWidget *parent):
auto margin = Theme::previewIconMargin; auto margin = Theme::previewIconMargin;
auto borderRadius = Theme::previewIconBorderRadius; auto borderRadius = Theme::previewIconBorderRadius;
setStyleSheet( setStyleSheet(
"QListView::item {border:" + QString::number(borderSize) + "px solid transparent; margin:" + QString::number(margin) + "px; background-color: " + Theme::gray.name() +"; border-radius: " + QString::number(borderRadius) + ";}" + "QListView::item {border:" + QString::number(borderSize) + "px solid transparent; margin:" + QString::number(margin) + "px; background-color: " + Theme::gray.name() + "; border-radius: " + QString::number(borderRadius) + ";}" + "QListView::item:selected {border-color: " + Theme::red.name() + ";}");
"QListView::item:selected {border-color: " + Theme::red.name() + ";}"
);
setViewMode(QListView::IconMode); setViewMode(QListView::IconMode);
setGridSize(QSize(Theme::partPreviewImageSize, Theme::partPreviewImageSize)); setGridSize(QSize(Theme::partPreviewImageSize, Theme::partPreviewImageSize));

View File

@ -3,11 +3,10 @@
#include <QListView> #include <QListView>
class PreviewGridView: public QListView class PreviewGridView : public QListView {
{
Q_OBJECT Q_OBJECT
public: public:
PreviewGridView(QWidget *parent=nullptr); PreviewGridView(QWidget* parent = nullptr);
}; };
#endif #endif

View File

@ -1,7 +1,7 @@
#include <QDebug>
#include "skeleton_document.h" #include "skeleton_document.h"
#include <QDebug>
const SkeletonNode *SkeletonDocument::findNode(dust3d::Uuid nodeId) const const SkeletonNode* SkeletonDocument::findNode(dust3d::Uuid nodeId) const
{ {
auto it = nodeMap.find(nodeId); auto it = nodeMap.find(nodeId);
if (it == nodeMap.end()) if (it == nodeMap.end())
@ -9,7 +9,7 @@ const SkeletonNode *SkeletonDocument::findNode(dust3d::Uuid nodeId) const
return &it->second; return &it->second;
} }
const SkeletonEdge *SkeletonDocument::findEdge(dust3d::Uuid edgeId) const const SkeletonEdge* SkeletonDocument::findEdge(dust3d::Uuid edgeId) const
{ {
auto it = edgeMap.find(edgeId); auto it = edgeMap.find(edgeId);
if (it == edgeMap.end()) if (it == edgeMap.end())
@ -17,7 +17,7 @@ const SkeletonEdge *SkeletonDocument::findEdge(dust3d::Uuid edgeId) const
return &it->second; return &it->second;
} }
const SkeletonPart *SkeletonDocument::findPart(dust3d::Uuid partId) const const SkeletonPart* SkeletonDocument::findPart(dust3d::Uuid partId) const
{ {
auto it = partMap.find(partId); auto it = partMap.find(partId);
if (it == partMap.end()) if (it == partMap.end())
@ -25,9 +25,9 @@ const SkeletonPart *SkeletonDocument::findPart(dust3d::Uuid partId) const
return &it->second; return &it->second;
} }
const SkeletonEdge *SkeletonDocument::findEdgeByNodes(dust3d::Uuid firstNodeId, dust3d::Uuid secondNodeId) const const SkeletonEdge* SkeletonDocument::findEdgeByNodes(dust3d::Uuid firstNodeId, dust3d::Uuid secondNodeId) const
{ {
const SkeletonNode *firstNode = nullptr; const SkeletonNode* firstNode = nullptr;
firstNode = findNode(firstNodeId); firstNode = findNode(firstNodeId);
if (nullptr == firstNode) { if (nullptr == firstNode) {
return nullptr; return nullptr;
@ -43,18 +43,18 @@ const SkeletonEdge *SkeletonDocument::findEdgeByNodes(dust3d::Uuid firstNodeId,
return nullptr; return nullptr;
} }
void SkeletonDocument::findAllNeighbors(dust3d::Uuid nodeId, std::set<dust3d::Uuid> &neighbors) const void SkeletonDocument::findAllNeighbors(dust3d::Uuid nodeId, std::set<dust3d::Uuid>& neighbors) const
{ {
const auto &node = findNode(nodeId); const auto& node = findNode(nodeId);
if (nullptr == node) { if (nullptr == node) {
return; return;
} }
for (const auto &edgeId: node->edgeIds) { for (const auto& edgeId : node->edgeIds) {
const auto &edge = findEdge(edgeId); const auto& edge = findEdge(edgeId);
if (nullptr == edge) { if (nullptr == edge) {
continue; continue;
} }
const auto &neighborNodeId = edge->neighborOf(nodeId); const auto& neighborNodeId = edge->neighborOf(nodeId);
if (neighborNodeId.isNull()) { if (neighborNodeId.isNull()) {
continue; continue;
} }
@ -68,7 +68,7 @@ void SkeletonDocument::findAllNeighbors(dust3d::Uuid nodeId, std::set<dust3d::Uu
bool SkeletonDocument::isNodeConnectable(dust3d::Uuid nodeId) const bool SkeletonDocument::isNodeConnectable(dust3d::Uuid nodeId) const
{ {
const auto &node = findNode(nodeId); const auto& node = findNode(nodeId);
if (nullptr == node) if (nullptr == node)
return false; return false;
if (node->edgeIds.size() < 2) if (node->edgeIds.size() < 2)
@ -78,7 +78,7 @@ bool SkeletonDocument::isNodeConnectable(dust3d::Uuid nodeId) const
void SkeletonDocument::reduceNode(dust3d::Uuid nodeId) void SkeletonDocument::reduceNode(dust3d::Uuid nodeId)
{ {
const SkeletonNode *node = findNode(nodeId); const SkeletonNode* node = findNode(nodeId);
if (nullptr == node) { if (nullptr == node) {
return; return;
} }
@ -87,11 +87,11 @@ void SkeletonDocument::reduceNode(dust3d::Uuid nodeId)
} }
dust3d::Uuid firstEdgeId = node->edgeIds[0]; dust3d::Uuid firstEdgeId = node->edgeIds[0];
dust3d::Uuid secondEdgeId = node->edgeIds[1]; dust3d::Uuid secondEdgeId = node->edgeIds[1];
const SkeletonEdge *firstEdge = findEdge(firstEdgeId); const SkeletonEdge* firstEdge = findEdge(firstEdgeId);
if (nullptr == firstEdge) { if (nullptr == firstEdge) {
return; return;
} }
const SkeletonEdge *secondEdge = findEdge(secondEdgeId); const SkeletonEdge* secondEdge = findEdge(secondEdgeId);
if (nullptr == secondEdge) { if (nullptr == secondEdge) {
return; return;
} }
@ -103,7 +103,7 @@ void SkeletonDocument::reduceNode(dust3d::Uuid nodeId)
void SkeletonDocument::breakEdge(dust3d::Uuid edgeId) void SkeletonDocument::breakEdge(dust3d::Uuid edgeId)
{ {
const SkeletonEdge *edge = findEdge(edgeId); const SkeletonEdge* edge = findEdge(edgeId);
if (nullptr == edge) { if (nullptr == edge) {
return; return;
} }
@ -112,11 +112,11 @@ void SkeletonDocument::breakEdge(dust3d::Uuid edgeId)
} }
dust3d::Uuid firstNodeId = edge->nodeIds[0]; dust3d::Uuid firstNodeId = edge->nodeIds[0];
dust3d::Uuid secondNodeId = edge->nodeIds[1]; dust3d::Uuid secondNodeId = edge->nodeIds[1];
const SkeletonNode *firstNode = findNode(firstNodeId); const SkeletonNode* firstNode = findNode(firstNodeId);
if (nullptr == firstNode) { if (nullptr == firstNode) {
return; return;
} }
const SkeletonNode *secondNode = findNode(secondNodeId); const SkeletonNode* secondNode = findNode(secondNodeId);
if (nullptr == secondNode) { if (nullptr == secondNode) {
return; return;
} }
@ -134,7 +134,7 @@ void SkeletonDocument::breakEdge(dust3d::Uuid edgeId)
void SkeletonDocument::reverseEdge(dust3d::Uuid edgeId) void SkeletonDocument::reverseEdge(dust3d::Uuid edgeId)
{ {
SkeletonEdge *edge = (SkeletonEdge *)findEdge(edgeId); SkeletonEdge* edge = (SkeletonEdge*)findEdge(edgeId);
if (nullptr == edge) { if (nullptr == edge) {
return; return;
} }
@ -151,13 +151,13 @@ void SkeletonDocument::reverseEdge(dust3d::Uuid edgeId)
void SkeletonDocument::removeEdge(dust3d::Uuid edgeId) void SkeletonDocument::removeEdge(dust3d::Uuid edgeId)
{ {
const SkeletonEdge *edge = findEdge(edgeId); const SkeletonEdge* edge = findEdge(edgeId);
if (nullptr == edge) { if (nullptr == edge) {
return; return;
} }
if (isPartReadonly(edge->partId)) if (isPartReadonly(edge->partId))
return; return;
const SkeletonPart *oldPart = findPart(edge->partId); const SkeletonPart* oldPart = findPart(edge->partId);
if (nullptr == oldPart) { if (nullptr == oldPart) {
return; return;
} }
@ -169,7 +169,7 @@ void SkeletonDocument::removeEdge(dust3d::Uuid edgeId)
std::vector<dust3d::Uuid> newPartIds; std::vector<dust3d::Uuid> newPartIds;
for (auto groupIt = groups.begin(); groupIt != groups.end(); groupIt++) { for (auto groupIt = groups.begin(); groupIt != groups.end(); groupIt++) {
const auto newUuid = dust3d::Uuid::createUuid(); const auto newUuid = dust3d::Uuid::createUuid();
SkeletonPart &part = partMap[newUuid]; SkeletonPart& part = partMap[newUuid];
part.id = newUuid; part.id = newUuid;
part.copyAttributes(*oldPart); part.copyAttributes(*oldPart);
part.name = nextPartName; part.name = nextPartName;
@ -189,7 +189,7 @@ void SkeletonDocument::removeEdge(dust3d::Uuid edgeId)
} }
} }
addPartToComponent(part.id, findComponentParentId(part.componentId)); addPartToComponent(part.id, findComponentParentId(part.componentId));
newPartNodeNumMap.push_back({part.id, part.nodeIds.size()}); newPartNodeNumMap.push_back({ part.id, part.nodeIds.size() });
newPartIds.push_back(part.id); newPartIds.push_back(part.id);
emit partAdded(part.id); emit partAdded(part.id);
} }
@ -204,27 +204,26 @@ void SkeletonDocument::removeEdge(dust3d::Uuid edgeId)
edgeMap.erase(edgeId); edgeMap.erase(edgeId);
emit edgeRemoved(edgeId); emit edgeRemoved(edgeId);
removePart(oldPartId); removePart(oldPartId);
if (!newPartNodeNumMap.empty()) { if (!newPartNodeNumMap.empty()) {
std::sort(newPartNodeNumMap.begin(), newPartNodeNumMap.end(), [&]( std::sort(newPartNodeNumMap.begin(), newPartNodeNumMap.end(), [&](const std::pair<dust3d::Uuid, size_t>& first, const std::pair<dust3d::Uuid, size_t>& second) {
const std::pair<dust3d::Uuid, size_t> &first, const std::pair<dust3d::Uuid, size_t> &second) {
return first.second > second.second; return first.second > second.second;
}); });
updateLinkedPart(oldPartId, newPartNodeNumMap[0].first); updateLinkedPart(oldPartId, newPartNodeNumMap[0].first);
} }
emit skeletonChanged(); emit skeletonChanged();
} }
void SkeletonDocument::removeNode(dust3d::Uuid nodeId) void SkeletonDocument::removeNode(dust3d::Uuid nodeId)
{ {
const SkeletonNode *node = findNode(nodeId); const SkeletonNode* node = findNode(nodeId);
if (nullptr == node) { if (nullptr == node) {
return; return;
} }
if (isPartReadonly(node->partId)) if (isPartReadonly(node->partId))
return; return;
const SkeletonPart *oldPart = findPart(node->partId); const SkeletonPart* oldPart = findPart(node->partId);
if (nullptr == oldPart) { if (nullptr == oldPart) {
return; return;
} }
@ -236,7 +235,7 @@ void SkeletonDocument::removeNode(dust3d::Uuid nodeId)
std::vector<dust3d::Uuid> newPartIds; std::vector<dust3d::Uuid> newPartIds;
for (auto groupIt = groups.begin(); groupIt != groups.end(); groupIt++) { for (auto groupIt = groups.begin(); groupIt != groups.end(); groupIt++) {
const auto newUuid = dust3d::Uuid::createUuid(); const auto newUuid = dust3d::Uuid::createUuid();
SkeletonPart &part = partMap[newUuid]; SkeletonPart& part = partMap[newUuid];
part.id = newUuid; part.id = newUuid;
part.copyAttributes(*oldPart); part.copyAttributes(*oldPart);
part.name = nextPartName; part.name = nextPartName;
@ -256,7 +255,7 @@ void SkeletonDocument::removeNode(dust3d::Uuid nodeId)
} }
} }
addPartToComponent(part.id, findComponentParentId(part.componentId)); addPartToComponent(part.id, findComponentParentId(part.componentId));
newPartNodeNumMap.push_back({part.id, part.nodeIds.size()}); newPartNodeNumMap.push_back({ part.id, part.nodeIds.size() });
newPartIds.push_back(part.id); newPartIds.push_back(part.id);
emit partAdded(part.id); emit partAdded(part.id);
} }
@ -277,15 +276,14 @@ void SkeletonDocument::removeNode(dust3d::Uuid nodeId)
nodeMap.erase(nodeId); nodeMap.erase(nodeId);
emit nodeRemoved(nodeId); emit nodeRemoved(nodeId);
removePart(oldPartId); removePart(oldPartId);
if (!newPartNodeNumMap.empty()) { if (!newPartNodeNumMap.empty()) {
std::sort(newPartNodeNumMap.begin(), newPartNodeNumMap.end(), [&]( std::sort(newPartNodeNumMap.begin(), newPartNodeNumMap.end(), [&](const std::pair<dust3d::Uuid, size_t>& first, const std::pair<dust3d::Uuid, size_t>& second) {
const std::pair<dust3d::Uuid, size_t> &first, const std::pair<dust3d::Uuid, size_t> &second) {
return first.second > second.second; return first.second > second.second;
}); });
updateLinkedPart(oldPartId, newPartNodeNumMap[0].first); updateLinkedPart(oldPartId, newPartNodeNumMap[0].first);
} }
emit skeletonChanged(); emit skeletonChanged();
} }
@ -302,11 +300,11 @@ void SkeletonDocument::addNodeWithId(dust3d::Uuid nodeId, float x, float y, floa
dust3d::Uuid SkeletonDocument::createNode(dust3d::Uuid nodeId, float x, float y, float z, float radius, dust3d::Uuid fromNodeId) dust3d::Uuid SkeletonDocument::createNode(dust3d::Uuid nodeId, float x, float y, float z, float radius, dust3d::Uuid fromNodeId)
{ {
dust3d::Uuid partId; dust3d::Uuid partId;
const SkeletonNode *fromNode = nullptr; const SkeletonNode* fromNode = nullptr;
bool newPartAdded = false; bool newPartAdded = false;
if (fromNodeId.isNull()) { if (fromNodeId.isNull()) {
const auto newUuid = dust3d::Uuid::createUuid(); const auto newUuid = dust3d::Uuid::createUuid();
SkeletonPart &part = partMap[newUuid]; SkeletonPart& part = partMap[newUuid];
part.id = newUuid; part.id = newUuid;
partId = part.id; partId = part.id;
emit partAdded(partId); emit partAdded(partId);
@ -331,35 +329,35 @@ dust3d::Uuid SkeletonDocument::createNode(dust3d::Uuid nodeId, float x, float y,
node.setZ(z); node.setZ(z);
nodeMap[node.id] = node; nodeMap[node.id] = node;
partMap[partId].nodeIds.push_back(node.id); partMap[partId].nodeIds.push_back(node.id);
emit nodeAdded(node.id); emit nodeAdded(node.id);
if (nullptr != fromNode) { if (nullptr != fromNode) {
SkeletonEdge edge; SkeletonEdge edge;
edge.partId = partId; edge.partId = partId;
edge.nodeIds.push_back(fromNode->id); edge.nodeIds.push_back(fromNode->id);
edge.nodeIds.push_back(node.id); edge.nodeIds.push_back(node.id);
edgeMap[edge.id] = edge; edgeMap[edge.id] = edge;
nodeMap[node.id].edgeIds.push_back(edge.id); nodeMap[node.id].edgeIds.push_back(edge.id);
nodeMap[fromNode->id].edgeIds.push_back(edge.id); nodeMap[fromNode->id].edgeIds.push_back(edge.id);
emit edgeAdded(edge.id); emit edgeAdded(edge.id);
} }
if (newPartAdded) if (newPartAdded)
addPartToComponent(partId, m_currentCanvasComponentId); addPartToComponent(partId, m_currentCanvasComponentId);
emit skeletonChanged(); emit skeletonChanged();
return node.id; return node.id;
} }
void SkeletonDocument::joinNodeAndNeiborsToGroup(std::vector<dust3d::Uuid> *group, dust3d::Uuid nodeId, std::set<dust3d::Uuid> *visitMap, dust3d::Uuid noUseEdgeId) void SkeletonDocument::joinNodeAndNeiborsToGroup(std::vector<dust3d::Uuid>* group, dust3d::Uuid nodeId, std::set<dust3d::Uuid>* visitMap, dust3d::Uuid noUseEdgeId)
{ {
if (nodeId.isNull() || visitMap->find(nodeId) != visitMap->end()) if (nodeId.isNull() || visitMap->find(nodeId) != visitMap->end())
return; return;
const SkeletonNode *node = findNode(nodeId); const SkeletonNode* node = findNode(nodeId);
if (nullptr == node) { if (nullptr == node) {
return; return;
} }
@ -368,7 +366,7 @@ void SkeletonDocument::joinNodeAndNeiborsToGroup(std::vector<dust3d::Uuid> *grou
for (auto edgeIt = node->edgeIds.begin(); edgeIt != node->edgeIds.end(); edgeIt++) { for (auto edgeIt = node->edgeIds.begin(); edgeIt != node->edgeIds.end(); edgeIt++) {
if (noUseEdgeId == *edgeIt) if (noUseEdgeId == *edgeIt)
continue; continue;
const SkeletonEdge *edge = findEdge(*edgeIt); const SkeletonEdge* edge = findEdge(*edgeIt);
if (nullptr == edge) { if (nullptr == edge) {
continue; continue;
} }
@ -378,14 +376,14 @@ void SkeletonDocument::joinNodeAndNeiborsToGroup(std::vector<dust3d::Uuid> *grou
} }
} }
void SkeletonDocument::splitPartByNode(std::vector<std::vector<dust3d::Uuid>> *groups, dust3d::Uuid nodeId) void SkeletonDocument::splitPartByNode(std::vector<std::vector<dust3d::Uuid>>* groups, dust3d::Uuid nodeId)
{ {
const SkeletonNode *node = findNode(nodeId); const SkeletonNode* node = findNode(nodeId);
std::set<dust3d::Uuid> visitMap; std::set<dust3d::Uuid> visitMap;
visitMap.insert(nodeId); visitMap.insert(nodeId);
for (auto edgeIt = node->edgeIds.begin(); edgeIt != node->edgeIds.end(); edgeIt++) { for (auto edgeIt = node->edgeIds.begin(); edgeIt != node->edgeIds.end(); edgeIt++) {
std::vector<dust3d::Uuid> group; std::vector<dust3d::Uuid> group;
const SkeletonEdge *edge = findEdge(*edgeIt); const SkeletonEdge* edge = findEdge(*edgeIt);
if (nullptr == edge) { if (nullptr == edge) {
continue; continue;
} }
@ -395,9 +393,9 @@ void SkeletonDocument::splitPartByNode(std::vector<std::vector<dust3d::Uuid>> *g
} }
} }
void SkeletonDocument::splitPartByEdge(std::vector<std::vector<dust3d::Uuid>> *groups, dust3d::Uuid edgeId) void SkeletonDocument::splitPartByEdge(std::vector<std::vector<dust3d::Uuid>>* groups, dust3d::Uuid edgeId)
{ {
const SkeletonEdge *edge = findEdge(edgeId); const SkeletonEdge* edge = findEdge(edgeId);
if (nullptr == edge) { if (nullptr == edge) {
return; return;
} }
@ -410,17 +408,17 @@ void SkeletonDocument::splitPartByEdge(std::vector<std::vector<dust3d::Uuid>> *g
} }
} }
const SkeletonComponent *SkeletonDocument::findComponentParent(dust3d::Uuid componentId) const const SkeletonComponent* SkeletonDocument::findComponentParent(dust3d::Uuid componentId) const
{ {
auto component = componentMap.find(componentId); auto component = componentMap.find(componentId);
if (component == componentMap.end()) { if (component == componentMap.end()) {
return nullptr; return nullptr;
} }
if (component->second.parentId.isNull()) if (component->second.parentId.isNull())
return &rootComponent; return &rootComponent;
return (SkeletonComponent *)findComponent(component->second.parentId); return (SkeletonComponent*)findComponent(component->second.parentId);
} }
dust3d::Uuid SkeletonDocument::findComponentParentId(dust3d::Uuid componentId) const dust3d::Uuid SkeletonDocument::findComponentParentId(dust3d::Uuid componentId) const
@ -429,18 +427,18 @@ dust3d::Uuid SkeletonDocument::findComponentParentId(dust3d::Uuid componentId) c
if (component == componentMap.end()) { if (component == componentMap.end()) {
return dust3d::Uuid(); return dust3d::Uuid();
} }
return component->second.parentId; return component->second.parentId;
} }
void SkeletonDocument::moveComponentUp(dust3d::Uuid componentId) void SkeletonDocument::moveComponentUp(dust3d::Uuid componentId)
{ {
SkeletonComponent *parent = (SkeletonComponent *)findComponentParent(componentId); SkeletonComponent* parent = (SkeletonComponent*)findComponentParent(componentId);
if (nullptr == parent) if (nullptr == parent)
return; return;
dust3d::Uuid parentId = findComponentParentId(componentId); dust3d::Uuid parentId = findComponentParentId(componentId);
parent->moveChildUp(componentId); parent->moveChildUp(componentId);
parent->dirty = true; parent->dirty = true;
emit componentChildrenChanged(parentId); emit componentChildrenChanged(parentId);
@ -449,12 +447,12 @@ void SkeletonDocument::moveComponentUp(dust3d::Uuid componentId)
void SkeletonDocument::moveComponentDown(dust3d::Uuid componentId) void SkeletonDocument::moveComponentDown(dust3d::Uuid componentId)
{ {
SkeletonComponent *parent = (SkeletonComponent *)findComponentParent(componentId); SkeletonComponent* parent = (SkeletonComponent*)findComponentParent(componentId);
if (nullptr == parent) if (nullptr == parent)
return; return;
dust3d::Uuid parentId = findComponentParentId(componentId); dust3d::Uuid parentId = findComponentParentId(componentId);
parent->moveChildDown(componentId); parent->moveChildDown(componentId);
parent->dirty = true; parent->dirty = true;
emit componentChildrenChanged(parentId); emit componentChildrenChanged(parentId);
@ -463,12 +461,12 @@ void SkeletonDocument::moveComponentDown(dust3d::Uuid componentId)
void SkeletonDocument::moveComponentToTop(dust3d::Uuid componentId) void SkeletonDocument::moveComponentToTop(dust3d::Uuid componentId)
{ {
SkeletonComponent *parent = (SkeletonComponent *)findComponentParent(componentId); SkeletonComponent* parent = (SkeletonComponent*)findComponentParent(componentId);
if (nullptr == parent) if (nullptr == parent)
return; return;
dust3d::Uuid parentId = findComponentParentId(componentId); dust3d::Uuid parentId = findComponentParentId(componentId);
parent->moveChildToTop(componentId); parent->moveChildToTop(componentId);
parent->dirty = true; parent->dirty = true;
emit componentChildrenChanged(parentId); emit componentChildrenChanged(parentId);
@ -477,12 +475,12 @@ void SkeletonDocument::moveComponentToTop(dust3d::Uuid componentId)
void SkeletonDocument::moveComponentToBottom(dust3d::Uuid componentId) void SkeletonDocument::moveComponentToBottom(dust3d::Uuid componentId)
{ {
SkeletonComponent *parent = (SkeletonComponent *)findComponentParent(componentId); SkeletonComponent* parent = (SkeletonComponent*)findComponentParent(componentId);
if (nullptr == parent) if (nullptr == parent)
return; return;
dust3d::Uuid parentId = findComponentParentId(componentId); dust3d::Uuid parentId = findComponentParentId(componentId);
parent->moveChildToBottom(componentId); parent->moveChildToBottom(componentId);
parent->dirty = true; parent->dirty = true;
emit componentChildrenChanged(parentId); emit componentChildrenChanged(parentId);
@ -495,10 +493,10 @@ void SkeletonDocument::renameComponent(dust3d::Uuid componentId, QString name)
if (component == componentMap.end()) { if (component == componentMap.end()) {
return; return;
} }
if (component->second.name == name) if (component->second.name == name)
return; return;
if (!name.trimmed().isEmpty()) if (!name.trimmed().isEmpty())
component->second.name = name; component->second.name = name;
emit componentNameChanged(componentId); emit componentNameChanged(componentId);
@ -511,20 +509,20 @@ void SkeletonDocument::setComponentExpandState(dust3d::Uuid componentId, bool ex
if (component == componentMap.end()) { if (component == componentMap.end()) {
return; return;
} }
if (component->second.expanded == expanded) if (component->second.expanded == expanded)
return; return;
component->second.expanded = expanded; component->second.expanded = expanded;
emit componentExpandStateChanged(componentId); emit componentExpandStateChanged(componentId);
emit optionsChanged(); emit optionsChanged();
} }
void SkeletonDocument::ungroupComponent(const dust3d::Uuid &componentId) void SkeletonDocument::ungroupComponent(const dust3d::Uuid& componentId)
{ {
if (componentId.isNull()) if (componentId.isNull())
return; return;
SkeletonComponent *component = (SkeletonComponent *)findComponent(componentId); SkeletonComponent* component = (SkeletonComponent*)findComponent(componentId);
if (nullptr == component) { if (nullptr == component) {
dust3dDebug << "Component not found:" << componentId.toString(); dust3dDebug << "Component not found:" << componentId.toString();
return; return;
@ -532,15 +530,15 @@ void SkeletonDocument::ungroupComponent(const dust3d::Uuid &componentId)
if (component->childrenIds.empty()) if (component->childrenIds.empty())
return; return;
auto childrenIds = component->childrenIds; auto childrenIds = component->childrenIds;
SkeletonComponent *newParent = (SkeletonComponent *)findComponentParent(componentId); SkeletonComponent* newParent = (SkeletonComponent*)findComponentParent(componentId);
if (nullptr == newParent) { if (nullptr == newParent) {
dust3dDebug << "Expected parent component to be found, component:" << componentId.toString(); dust3dDebug << "Expected parent component to be found, component:" << componentId.toString();
return; return;
} }
auto newParentId = newParent->id; auto newParentId = newParent->id;
newParent->replaceChildWithOthers(componentId, childrenIds); newParent->replaceChildWithOthers(componentId, childrenIds);
for (const auto &childId: childrenIds) { for (const auto& childId : childrenIds) {
SkeletonComponent *child = (SkeletonComponent *)findComponent(childId); SkeletonComponent* child = (SkeletonComponent*)findComponent(childId);
if (nullptr == child) if (nullptr == child)
continue; continue;
child->parentId = newParentId; child->parentId = newParentId;
@ -551,7 +549,7 @@ void SkeletonDocument::ungroupComponent(const dust3d::Uuid &componentId)
emit skeletonChanged(); emit skeletonChanged();
} }
void SkeletonDocument::groupComponents(const std::vector<dust3d::Uuid> &componentIds) void SkeletonDocument::groupComponents(const std::vector<dust3d::Uuid>& componentIds)
{ {
if (componentIds.empty()) if (componentIds.empty())
return; return;
@ -563,7 +561,7 @@ void SkeletonDocument::groupComponents(const std::vector<dust3d::Uuid> &componen
auto it = componentIds.begin(); auto it = componentIds.begin();
SkeletonComponent *oldParent = (SkeletonComponent *)findComponentParent(*it); SkeletonComponent* oldParent = (SkeletonComponent*)findComponentParent(*it);
if (nullptr == oldParent) { if (nullptr == oldParent) {
dust3dDebug << "Expected parent component to be found, component:" << it->toString(); dust3dDebug << "Expected parent component to be found, component:" << it->toString();
return; return;
@ -574,7 +572,7 @@ void SkeletonDocument::groupComponents(const std::vector<dust3d::Uuid> &componen
oldParent->removeChild(*it); oldParent->removeChild(*it);
} }
for (const auto &componentId: componentIds) { for (const auto& componentId : componentIds) {
auto component = componentMap.find(componentId); auto component = componentMap.find(componentId);
if (component == componentMap.end()) { if (component == componentMap.end()) {
continue; continue;
@ -594,21 +592,21 @@ void SkeletonDocument::groupComponents(const std::vector<dust3d::Uuid> &componen
void SkeletonDocument::createNewChildComponent(dust3d::Uuid parentComponentId) void SkeletonDocument::createNewChildComponent(dust3d::Uuid parentComponentId)
{ {
SkeletonComponent *parentComponent = (SkeletonComponent *)findComponent(parentComponentId); SkeletonComponent* parentComponent = (SkeletonComponent*)findComponent(parentComponentId);
if (!parentComponent->linkToPartId.isNull()) { if (!parentComponent->linkToPartId.isNull()) {
parentComponentId = parentComponent->parentId; parentComponentId = parentComponent->parentId;
parentComponent = (SkeletonComponent *)findComponent(parentComponentId); parentComponent = (SkeletonComponent*)findComponent(parentComponentId);
} }
SkeletonComponent newComponent(dust3d::Uuid::createUuid()); SkeletonComponent newComponent(dust3d::Uuid::createUuid());
newComponent.name = tr("Group") + " " + QString::number(componentMap.size() - partMap.size() + 1); newComponent.name = tr("Group") + " " + QString::number(componentMap.size() - partMap.size() + 1);
parentComponent->addChild(newComponent.id); parentComponent->addChild(newComponent.id);
newComponent.parentId = parentComponentId; newComponent.parentId = parentComponentId;
auto newComponentId = newComponent.id; auto newComponentId = newComponent.id;
componentMap.emplace(newComponentId, std::move(newComponent)); componentMap.emplace(newComponentId, std::move(newComponent));
emit componentChildrenChanged(parentComponentId); emit componentChildrenChanged(parentComponentId);
emit componentAdded(newComponentId); emit componentAdded(newComponentId);
emit optionsChanged(); emit optionsChanged();
@ -620,12 +618,12 @@ void SkeletonDocument::removePart(dust3d::Uuid partId)
if (part == partMap.end()) { if (part == partMap.end()) {
return; return;
} }
if (!part->second.componentId.isNull()) { if (!part->second.componentId.isNull()) {
removeComponent(part->second.componentId); removeComponent(part->second.componentId);
return; return;
} }
removePartDontCareComponent(partId); removePartDontCareComponent(partId);
} }
@ -635,10 +633,10 @@ void SkeletonDocument::removePartDontCareComponent(dust3d::Uuid partId)
if (part == partMap.end()) { if (part == partMap.end()) {
return; return;
} }
std::vector<dust3d::Uuid> removedNodeIds; std::vector<dust3d::Uuid> removedNodeIds;
std::vector<dust3d::Uuid> removedEdgeIds; std::vector<dust3d::Uuid> removedEdgeIds;
for (auto nodeIt = nodeMap.begin(); nodeIt != nodeMap.end();) { for (auto nodeIt = nodeMap.begin(); nodeIt != nodeMap.end();) {
if (nodeIt->second.partId != partId) { if (nodeIt->second.partId != partId) {
nodeIt++; nodeIt++;
@ -647,7 +645,7 @@ void SkeletonDocument::removePartDontCareComponent(dust3d::Uuid partId)
removedNodeIds.push_back(nodeIt->second.id); removedNodeIds.push_back(nodeIt->second.id);
nodeIt = nodeMap.erase(nodeIt); nodeIt = nodeMap.erase(nodeIt);
} }
for (auto edgeIt = edgeMap.begin(); edgeIt != edgeMap.end();) { for (auto edgeIt = edgeMap.begin(); edgeIt != edgeMap.end();) {
if (edgeIt->second.partId != partId) { if (edgeIt->second.partId != partId) {
edgeIt++; edgeIt++;
@ -656,13 +654,13 @@ void SkeletonDocument::removePartDontCareComponent(dust3d::Uuid partId)
removedEdgeIds.push_back(edgeIt->second.id); removedEdgeIds.push_back(edgeIt->second.id);
edgeIt = edgeMap.erase(edgeIt); edgeIt = edgeMap.erase(edgeIt);
} }
partMap.erase(part); partMap.erase(part);
for (const auto &nodeId: removedNodeIds) { for (const auto& nodeId : removedNodeIds) {
emit nodeRemoved(nodeId); emit nodeRemoved(nodeId);
} }
for (const auto &edgeId: removedEdgeIds) { for (const auto& edgeId : removedEdgeIds) {
emit edgeRemoved(edgeId); emit edgeRemoved(edgeId);
} }
emit partRemoved(partId); emit partRemoved(partId);
@ -671,7 +669,7 @@ void SkeletonDocument::removePartDontCareComponent(dust3d::Uuid partId)
void SkeletonDocument::addPartToComponent(dust3d::Uuid partId, dust3d::Uuid componentId) void SkeletonDocument::addPartToComponent(dust3d::Uuid partId, dust3d::Uuid componentId)
{ {
SkeletonComponent child(dust3d::Uuid::createUuid()); SkeletonComponent child(dust3d::Uuid::createUuid());
if (!componentId.isNull()) { if (!componentId.isNull()) {
auto parentComponent = componentMap.find(componentId); auto parentComponent = componentMap.find(componentId);
if (parentComponent == componentMap.end()) { if (parentComponent == componentMap.end()) {
@ -683,13 +681,13 @@ void SkeletonDocument::addPartToComponent(dust3d::Uuid partId, dust3d::Uuid comp
} else { } else {
rootComponent.addChild(child.id); rootComponent.addChild(child.id);
} }
partMap[partId].componentId = child.id; partMap[partId].componentId = child.id;
child.linkToPartId = partId; child.linkToPartId = partId;
child.parentId = componentId; child.parentId = componentId;
auto childId = child.id; auto childId = child.id;
componentMap.emplace(childId, std::move(child)); componentMap.emplace(childId, std::move(child));
emit componentChildrenChanged(componentId); emit componentChildrenChanged(componentId);
emit componentAdded(childId); emit componentAdded(childId);
} }
@ -706,16 +704,16 @@ void SkeletonDocument::removeComponentRecursively(dust3d::Uuid componentId)
if (component == componentMap.end()) { if (component == componentMap.end()) {
return; return;
} }
if (!component->second.linkToPartId.isNull()) { if (!component->second.linkToPartId.isNull()) {
removePartDontCareComponent(component->second.linkToPartId); removePartDontCareComponent(component->second.linkToPartId);
} }
auto childrenIds = component->second.childrenIds; auto childrenIds = component->second.childrenIds;
for (const auto &childId: childrenIds) { for (const auto& childId : childrenIds) {
removeComponentRecursively(childId); removeComponentRecursively(childId);
} }
dust3d::Uuid parentId = component->second.parentId; dust3d::Uuid parentId = component->second.parentId;
if (!parentId.isNull()) { if (!parentId.isNull()) {
auto parentComponent = componentMap.find(parentId); auto parentComponent = componentMap.find(parentId);
@ -726,7 +724,7 @@ void SkeletonDocument::removeComponentRecursively(dust3d::Uuid componentId)
} else { } else {
rootComponent.removeChild(componentId); rootComponent.removeChild(componentId);
} }
componentMap.erase(component); componentMap.erase(component);
emit componentRemoved(componentId); emit componentRemoved(componentId);
emit componentChildrenChanged(parentId); emit componentChildrenChanged(parentId);
@ -735,7 +733,7 @@ void SkeletonDocument::removeComponentRecursively(dust3d::Uuid componentId)
void SkeletonDocument::setCurrentCanvasComponentId(dust3d::Uuid componentId) void SkeletonDocument::setCurrentCanvasComponentId(dust3d::Uuid componentId)
{ {
m_currentCanvasComponentId = componentId; m_currentCanvasComponentId = componentId;
const SkeletonComponent *component = findComponent(m_currentCanvasComponentId); const SkeletonComponent* component = findComponent(m_currentCanvasComponentId);
if (nullptr == component) { if (nullptr == component) {
m_currentCanvasComponentId = dust3d::Uuid(); m_currentCanvasComponentId = dust3d::Uuid();
} else { } else {
@ -749,7 +747,7 @@ void SkeletonDocument::setCurrentCanvasComponentId(dust3d::Uuid componentId)
void SkeletonDocument::addComponent(dust3d::Uuid parentId) void SkeletonDocument::addComponent(dust3d::Uuid parentId)
{ {
SkeletonComponent component(dust3d::Uuid::createUuid()); SkeletonComponent component(dust3d::Uuid::createUuid());
if (!parentId.isNull()) { if (!parentId.isNull()) {
auto parentComponent = componentMap.find(parentId); auto parentComponent = componentMap.find(parentId);
if (parentComponent == componentMap.end()) { if (parentComponent == componentMap.end()) {
@ -759,18 +757,18 @@ void SkeletonDocument::addComponent(dust3d::Uuid parentId)
} else { } else {
rootComponent.addChild(component.id); rootComponent.addChild(component.id);
} }
component.parentId = parentId; component.parentId = parentId;
auto componentId = component.id; auto componentId = component.id;
componentMap.emplace(componentId, std::move(component)); componentMap.emplace(componentId, std::move(component));
emit componentChildrenChanged(parentId); emit componentChildrenChanged(parentId);
emit componentAdded(componentId); emit componentAdded(componentId);
} }
bool SkeletonDocument::isDescendantComponent(dust3d::Uuid componentId, dust3d::Uuid suspiciousId) bool SkeletonDocument::isDescendantComponent(dust3d::Uuid componentId, dust3d::Uuid suspiciousId)
{ {
const SkeletonComponent *loopComponent = findComponentParent(suspiciousId); const SkeletonComponent* loopComponent = findComponentParent(suspiciousId);
while (nullptr != loopComponent) { while (nullptr != loopComponent) {
if (loopComponent->id == componentId) if (loopComponent->id == componentId)
return true; return true;
@ -788,13 +786,13 @@ void SkeletonDocument::moveComponent(dust3d::Uuid componentId, dust3d::Uuid toPa
if (component == componentMap.end()) { if (component == componentMap.end()) {
return; return;
} }
if (component->second.parentId == toParentId) if (component->second.parentId == toParentId)
return; return;
if (isDescendantComponent(componentId, toParentId)) if (isDescendantComponent(componentId, toParentId))
return; return;
if (component->second.parentId.isNull()) { if (component->second.parentId.isNull()) {
rootComponent.removeChild(componentId); rootComponent.removeChild(componentId);
emit componentChildrenChanged(rootComponent.id); emit componentChildrenChanged(rootComponent.id);
@ -806,9 +804,9 @@ void SkeletonDocument::moveComponent(dust3d::Uuid componentId, dust3d::Uuid toPa
emit componentChildrenChanged(oldParent->second.id); emit componentChildrenChanged(oldParent->second.id);
} }
} }
component->second.parentId = toParentId; component->second.parentId = toParentId;
if (toParentId.isNull()) { if (toParentId.isNull()) {
rootComponent.addChild(componentId); rootComponent.addChild(componentId);
emit componentChildrenChanged(rootComponent.id); emit componentChildrenChanged(rootComponent.id);
@ -820,7 +818,7 @@ void SkeletonDocument::moveComponent(dust3d::Uuid componentId, dust3d::Uuid toPa
emit componentChildrenChanged(newParent->second.id); emit componentChildrenChanged(newParent->second.id);
} }
} }
emit skeletonChanged(); emit skeletonChanged();
} }
@ -864,25 +862,25 @@ void SkeletonDocument::setPartDisableState(dust3d::Uuid partId, bool disabled)
emit skeletonChanged(); emit skeletonChanged();
} }
void SkeletonDocument::collectComponentDescendantParts(dust3d::Uuid componentId, std::vector<dust3d::Uuid> &partIds) const void SkeletonDocument::collectComponentDescendantParts(dust3d::Uuid componentId, std::vector<dust3d::Uuid>& partIds) const
{ {
const SkeletonComponent *component = findComponent(componentId); const SkeletonComponent* component = findComponent(componentId);
if (nullptr == component) if (nullptr == component)
return; return;
if (!component->linkToPartId.isNull()) { if (!component->linkToPartId.isNull()) {
partIds.push_back(component->linkToPartId); partIds.push_back(component->linkToPartId);
return; return;
} }
for (const auto &childId: component->childrenIds) { for (const auto& childId : component->childrenIds) {
collectComponentDescendantParts(childId, partIds); collectComponentDescendantParts(childId, partIds);
} }
} }
void SkeletonDocument::collectComponentDescendantComponents(dust3d::Uuid componentId, std::vector<dust3d::Uuid> &componentIds) const void SkeletonDocument::collectComponentDescendantComponents(dust3d::Uuid componentId, std::vector<dust3d::Uuid>& componentIds) const
{ {
const SkeletonComponent *component = findComponent(componentId); const SkeletonComponent* component = findComponent(componentId);
if (nullptr == component) if (nullptr == component)
return; return;
@ -890,7 +888,7 @@ void SkeletonDocument::collectComponentDescendantComponents(dust3d::Uuid compone
return; return;
} }
for (const auto &childId: component->childrenIds) { for (const auto& childId : component->childrenIds) {
componentIds.push_back(childId); componentIds.push_back(childId);
collectComponentDescendantComponents(childId, componentIds); collectComponentDescendantComponents(childId, componentIds);
} }
@ -901,10 +899,10 @@ void SkeletonDocument::hideOtherComponents(dust3d::Uuid componentId)
std::vector<dust3d::Uuid> partIds; std::vector<dust3d::Uuid> partIds;
collectComponentDescendantParts(componentId, partIds); collectComponentDescendantParts(componentId, partIds);
std::set<dust3d::Uuid> partIdSet; std::set<dust3d::Uuid> partIdSet;
for (const auto &partId: partIds) { for (const auto& partId : partIds) {
partIdSet.insert(partId); partIdSet.insert(partId);
} }
for (const auto &part: partMap) { for (const auto& part : partMap) {
if (partIdSet.find(part.first) != partIdSet.end()) if (partIdSet.find(part.first) != partIdSet.end())
continue; continue;
setPartVisibleState(part.first, false); setPartVisibleState(part.first, false);
@ -916,10 +914,10 @@ void SkeletonDocument::lockOtherComponents(dust3d::Uuid componentId)
std::vector<dust3d::Uuid> partIds; std::vector<dust3d::Uuid> partIds;
collectComponentDescendantParts(componentId, partIds); collectComponentDescendantParts(componentId, partIds);
std::set<dust3d::Uuid> partIdSet; std::set<dust3d::Uuid> partIdSet;
for (const auto &partId: partIds) { for (const auto& partId : partIds) {
partIdSet.insert(partId); partIdSet.insert(partId);
} }
for (const auto &part: partMap) { for (const auto& part : partMap) {
if (partIdSet.find(part.first) != partIdSet.end()) if (partIdSet.find(part.first) != partIdSet.end())
continue; continue;
setPartLockState(part.first, true); setPartLockState(part.first, true);
@ -928,14 +926,14 @@ void SkeletonDocument::lockOtherComponents(dust3d::Uuid componentId)
void SkeletonDocument::hideAllComponents() void SkeletonDocument::hideAllComponents()
{ {
for (const auto &part: partMap) { for (const auto& part : partMap) {
setPartVisibleState(part.first, false); setPartVisibleState(part.first, false);
} }
} }
void SkeletonDocument::showAllComponents() void SkeletonDocument::showAllComponents()
{ {
for (const auto &part: partMap) { for (const auto& part : partMap) {
setPartVisibleState(part.first, true); setPartVisibleState(part.first, true);
} }
} }
@ -943,7 +941,7 @@ void SkeletonDocument::showAllComponents()
void SkeletonDocument::showOrHideAllComponents() void SkeletonDocument::showOrHideAllComponents()
{ {
bool foundVisiblePart = false; bool foundVisiblePart = false;
for (const auto &part: partMap) { for (const auto& part : partMap) {
if (part.second.visible) { if (part.second.visible) {
foundVisiblePart = true; foundVisiblePart = true;
} }
@ -956,7 +954,7 @@ void SkeletonDocument::showOrHideAllComponents()
void SkeletonDocument::collapseAllComponents() void SkeletonDocument::collapseAllComponents()
{ {
for (const auto &component: componentMap) { for (const auto& component : componentMap) {
if (!component.second.linkToPartId.isNull()) if (!component.second.linkToPartId.isNull())
continue; continue;
setComponentExpandState(component.first, false); setComponentExpandState(component.first, false);
@ -965,7 +963,7 @@ void SkeletonDocument::collapseAllComponents()
void SkeletonDocument::expandAllComponents() void SkeletonDocument::expandAllComponents()
{ {
for (const auto &component: componentMap) { for (const auto& component : componentMap) {
if (!component.second.linkToPartId.isNull()) if (!component.second.linkToPartId.isNull())
continue; continue;
setComponentExpandState(component.first, true); setComponentExpandState(component.first, true);
@ -974,14 +972,14 @@ void SkeletonDocument::expandAllComponents()
void SkeletonDocument::lockAllComponents() void SkeletonDocument::lockAllComponents()
{ {
for (const auto &part: partMap) { for (const auto& part : partMap) {
setPartLockState(part.first, true); setPartLockState(part.first, true);
} }
} }
void SkeletonDocument::unlockAllComponents() void SkeletonDocument::unlockAllComponents()
{ {
for (const auto &part: partMap) { for (const auto& part : partMap) {
setPartLockState(part.first, false); setPartLockState(part.first, false);
} }
} }
@ -990,7 +988,7 @@ void SkeletonDocument::hideDescendantComponents(dust3d::Uuid componentId)
{ {
std::vector<dust3d::Uuid> partIds; std::vector<dust3d::Uuid> partIds;
collectComponentDescendantParts(componentId, partIds); collectComponentDescendantParts(componentId, partIds);
for (const auto &partId: partIds) { for (const auto& partId : partIds) {
setPartVisibleState(partId, false); setPartVisibleState(partId, false);
} }
} }
@ -999,7 +997,7 @@ void SkeletonDocument::showDescendantComponents(dust3d::Uuid componentId)
{ {
std::vector<dust3d::Uuid> partIds; std::vector<dust3d::Uuid> partIds;
collectComponentDescendantParts(componentId, partIds); collectComponentDescendantParts(componentId, partIds);
for (const auto &partId: partIds) { for (const auto& partId : partIds) {
setPartVisibleState(partId, true); setPartVisibleState(partId, true);
} }
} }
@ -1008,7 +1006,7 @@ void SkeletonDocument::lockDescendantComponents(dust3d::Uuid componentId)
{ {
std::vector<dust3d::Uuid> partIds; std::vector<dust3d::Uuid> partIds;
collectComponentDescendantParts(componentId, partIds); collectComponentDescendantParts(componentId, partIds);
for (const auto &partId: partIds) { for (const auto& partId : partIds) {
setPartLockState(partId, true); setPartLockState(partId, true);
} }
} }
@ -1017,7 +1015,7 @@ void SkeletonDocument::unlockDescendantComponents(dust3d::Uuid componentId)
{ {
std::vector<dust3d::Uuid> partIds; std::vector<dust3d::Uuid> partIds;
collectComponentDescendantParts(componentId, partIds); collectComponentDescendantParts(componentId, partIds);
for (const auto &partId: partIds) { for (const auto& partId : partIds) {
setPartLockState(partId, false); setPartLockState(partId, false);
} }
} }
@ -1042,7 +1040,7 @@ void SkeletonDocument::scaleNodeByAddRadius(dust3d::Uuid nodeId, float amount)
bool SkeletonDocument::isPartReadonly(dust3d::Uuid partId) const bool SkeletonDocument::isPartReadonly(dust3d::Uuid partId) const
{ {
const SkeletonPart *part = findPart(partId); const SkeletonPart* part = findPart(partId);
if (nullptr == part) { if (nullptr == part) {
return true; return true;
} }
@ -1151,7 +1149,7 @@ void SkeletonDocument::switchNodeXZ(dust3d::Uuid nodeId)
emit skeletonChanged(); emit skeletonChanged();
} }
const SkeletonComponent *SkeletonDocument::findComponent(dust3d::Uuid componentId) const const SkeletonComponent* SkeletonDocument::findComponent(dust3d::Uuid componentId) const
{ {
if (componentId.isNull()) if (componentId.isNull())
return &rootComponent; return &rootComponent;
@ -1166,36 +1164,36 @@ void SkeletonDocument::addEdge(dust3d::Uuid fromNodeId, dust3d::Uuid toNodeId)
if (findEdgeByNodes(fromNodeId, toNodeId)) { if (findEdgeByNodes(fromNodeId, toNodeId)) {
return; return;
} }
const SkeletonNode *fromNode = nullptr; const SkeletonNode* fromNode = nullptr;
const SkeletonNode *toNode = nullptr; const SkeletonNode* toNode = nullptr;
bool toPartRemoved = false; bool toPartRemoved = false;
fromNode = findNode(fromNodeId); fromNode = findNode(fromNodeId);
if (nullptr == fromNode) { if (nullptr == fromNode) {
return; return;
} }
if (isPartReadonly(fromNode->partId)) if (isPartReadonly(fromNode->partId))
return; return;
toNode = findNode(toNodeId); toNode = findNode(toNodeId);
if (nullptr == toNode) { if (nullptr == toNode) {
return; return;
} }
if (isPartReadonly(toNode->partId)) if (isPartReadonly(toNode->partId))
return; return;
dust3d::Uuid toPartId = toNode->partId; dust3d::Uuid toPartId = toNode->partId;
auto fromPart = partMap.find(fromNode->partId); auto fromPart = partMap.find(fromNode->partId);
if (fromPart == partMap.end()) { if (fromPart == partMap.end()) {
return; return;
} }
fromPart->second.dirty = true; fromPart->second.dirty = true;
if (fromNode->partId != toNode->partId) { if (fromNode->partId != toNode->partId) {
toPartRemoved = true; toPartRemoved = true;
std::vector<dust3d::Uuid> toGroup; std::vector<dust3d::Uuid> toGroup;
@ -1217,7 +1215,7 @@ void SkeletonDocument::addEdge(dust3d::Uuid fromNodeId, dust3d::Uuid toNodeId)
} }
} }
} }
SkeletonEdge edge; SkeletonEdge edge;
edge.partId = fromNode->partId; edge.partId = fromNode->partId;
edge.nodeIds.push_back(fromNode->id); edge.nodeIds.push_back(fromNode->id);
@ -1226,34 +1224,34 @@ void SkeletonDocument::addEdge(dust3d::Uuid fromNodeId, dust3d::Uuid toNodeId)
nodeMap[toNodeId].edgeIds.push_back(edge.id); nodeMap[toNodeId].edgeIds.push_back(edge.id);
nodeMap[fromNode->id].edgeIds.push_back(edge.id); nodeMap[fromNode->id].edgeIds.push_back(edge.id);
emit edgeAdded(edge.id); emit edgeAdded(edge.id);
if (toPartRemoved) { if (toPartRemoved) {
updateLinkedPart(toPartId, fromNode->partId); updateLinkedPart(toPartId, fromNode->partId);
removePart(toPartId); removePart(toPartId);
} }
emit skeletonChanged(); emit skeletonChanged();
} }
void SkeletonDocument::updateLinkedPart(dust3d::Uuid oldPartId, dust3d::Uuid newPartId) void SkeletonDocument::updateLinkedPart(dust3d::Uuid oldPartId, dust3d::Uuid newPartId)
{ {
for (auto &partIt: partMap) { for (auto& partIt : partMap) {
if (partIt.second.cutFaceLinkedId == oldPartId) { if (partIt.second.cutFaceLinkedId == oldPartId) {
partIt.second.dirty = true; partIt.second.dirty = true;
partIt.second.setCutFaceLinkedId(newPartId); partIt.second.setCutFaceLinkedId(newPartId);
} }
} }
std::set<dust3d::Uuid> dirtyPartIds; std::set<dust3d::Uuid> dirtyPartIds;
for (auto &nodeIt: nodeMap) { for (auto& nodeIt : nodeMap) {
if (nodeIt.second.cutFaceLinkedId == oldPartId) { if (nodeIt.second.cutFaceLinkedId == oldPartId) {
dirtyPartIds.insert(nodeIt.second.partId); dirtyPartIds.insert(nodeIt.second.partId);
nodeIt.second.setCutFaceLinkedId(newPartId); nodeIt.second.setCutFaceLinkedId(newPartId);
} }
} }
for (const auto &partId: dirtyPartIds) { for (const auto& partId : dirtyPartIds) {
SkeletonPart *part = (SkeletonPart *)findPart(partId); SkeletonPart* part = (SkeletonPart*)findPart(partId);
if (nullptr == part) if (nullptr == part)
continue; continue;
part->dirty = true; part->dirty = true;
@ -1272,17 +1270,17 @@ void SkeletonDocument::disableAllPositionRelatedLocks()
void SkeletonDocument::resetDirtyFlags() void SkeletonDocument::resetDirtyFlags()
{ {
for (auto &part: partMap) { for (auto& part : partMap) {
part.second.dirty = false; part.second.dirty = false;
} }
for (auto &component: componentMap) { for (auto& component : componentMap) {
component.second.dirty = false; component.second.dirty = false;
} }
} }
void SkeletonDocument::markAllDirty() void SkeletonDocument::markAllDirty()
{ {
for (auto &part: partMap) { for (auto& part : partMap) {
part.second.dirty = true; part.second.dirty = true;
} }
} }
@ -1319,27 +1317,27 @@ void SkeletonDocument::setRadiusLockState(bool locked)
emit radiusLockStateChanged(); emit radiusLockStateChanged();
} }
void SkeletonDocument::setComponentPreviewImage(const dust3d::Uuid &componentId, std::unique_ptr<QImage> image) void SkeletonDocument::setComponentPreviewImage(const dust3d::Uuid& componentId, std::unique_ptr<QImage> image)
{ {
SkeletonComponent *component = (SkeletonComponent *)findComponent(componentId); SkeletonComponent* component = (SkeletonComponent*)findComponent(componentId);
if (nullptr == component) if (nullptr == component)
return; return;
component->isPreviewImageDecorationObsolete = true; component->isPreviewImageDecorationObsolete = true;
component->previewImage = std::move(image); component->previewImage = std::move(image);
} }
void SkeletonDocument::setComponentPreviewPixmap(const dust3d::Uuid &componentId, const QPixmap &pixmap) void SkeletonDocument::setComponentPreviewPixmap(const dust3d::Uuid& componentId, const QPixmap& pixmap)
{ {
SkeletonComponent *component = (SkeletonComponent *)findComponent(componentId); SkeletonComponent* component = (SkeletonComponent*)findComponent(componentId);
if (nullptr == component) if (nullptr == component)
return; return;
component->previewPixmap = pixmap; component->previewPixmap = pixmap;
emit componentPreviewPixmapChanged(componentId); emit componentPreviewPixmapChanged(componentId);
} }
void SkeletonDocument::setComponentPreviewMesh(const dust3d::Uuid &componentId, std::unique_ptr<ModelMesh> mesh) void SkeletonDocument::setComponentPreviewMesh(const dust3d::Uuid& componentId, std::unique_ptr<ModelMesh> mesh)
{ {
SkeletonComponent *component = (SkeletonComponent *)findComponent(componentId); SkeletonComponent* component = (SkeletonComponent*)findComponent(componentId);
if (nullptr == component) if (nullptr == component)
return; return;
component->updatePreviewMesh(std::move(mesh)); component->updatePreviewMesh(std::move(mesh));

View File

@ -1,35 +1,34 @@
#ifndef DUST3D_APPLICATION_SKELETON_DOCUMENT_H_ #ifndef DUST3D_APPLICATION_SKELETON_DOCUMENT_H_
#define DUST3D_APPLICATION_SKELETON_DOCUMENT_H_ #define DUST3D_APPLICATION_SKELETON_DOCUMENT_H_
#include <QObject>
#include <QString>
#include <cmath>
#include <QImage>
#include <QByteArray>
#include <QDebug>
#include <QVector3D>
#include <QPixmap>
#include <dust3d/base/uuid.h>
#include <dust3d/base/cut_face.h>
#include <dust3d/base/part_target.h>
#include <dust3d/base/part_base.h>
#include <dust3d/base/combine_mode.h>
#include "theme.h"
#include "model_mesh.h"
#include "debug.h" #include "debug.h"
#include "mesh_generator.h" #include "mesh_generator.h"
#include "model_mesh.h"
#include "theme.h"
#include <QByteArray>
#include <QDebug>
#include <QImage>
#include <QObject>
#include <QPixmap>
#include <QString>
#include <QVector3D>
#include <cmath>
#include <dust3d/base/combine_mode.h>
#include <dust3d/base/cut_face.h>
#include <dust3d/base/part_base.h>
#include <dust3d/base/part_target.h>
#include <dust3d/base/uuid.h>
class SkeletonNode class SkeletonNode {
{
public: public:
SkeletonNode(const dust3d::Uuid &withId=dust3d::Uuid()) : SkeletonNode(const dust3d::Uuid& withId = dust3d::Uuid())
radius(0), : radius(0)
cutRotation(0.0), , cutRotation(0.0)
cutFace(dust3d::CutFace::Quad), , cutFace(dust3d::CutFace::Quad)
hasCutFaceSettings(false), , hasCutFaceSettings(false)
m_x(0), , m_x(0)
m_y(0), , m_y(0)
m_z(0) , m_z(0)
{ {
id = withId.isNull() ? dust3d::Uuid::createUuid() : withId; id = withId.isNull() ? dust3d::Uuid::createUuid() : withId;
} }
@ -56,7 +55,7 @@ public:
cutFaceLinkedId = dust3d::Uuid(); cutFaceLinkedId = dust3d::Uuid();
hasCutFaceSettings = true; hasCutFaceSettings = true;
} }
void setCutFaceLinkedId(const dust3d::Uuid &linkedId) void setCutFaceLinkedId(const dust3d::Uuid& linkedId)
{ {
if (linkedId.isNull()) { if (linkedId.isNull()) {
clearCutFaceSettings(); clearCutFaceSettings();
@ -73,21 +72,21 @@ public:
cutRotation = 0; cutRotation = 0;
hasCutFaceSettings = false; hasCutFaceSettings = false;
} }
float getX(bool rotated=false) const float getX(bool rotated = false) const
{ {
if (rotated) if (rotated)
return m_y; return m_y;
return m_x; return m_x;
} }
float getY(bool rotated=false) const float getY(bool rotated = false) const
{ {
if (rotated) if (rotated)
return m_x; return m_x;
return m_y; return m_y;
} }
float getZ(bool rotated=false) const float getZ(bool rotated = false) const
{ {
(void) rotated; (void)rotated;
return m_z; return m_z;
} }
void setX(float x) void setX(float x)
@ -123,16 +122,16 @@ public:
dust3d::Uuid cutFaceLinkedId; dust3d::Uuid cutFaceLinkedId;
bool hasCutFaceSettings; bool hasCutFaceSettings;
std::vector<dust3d::Uuid> edgeIds; std::vector<dust3d::Uuid> edgeIds;
private: private:
float m_x; float m_x;
float m_y; float m_y;
float m_z; float m_z;
}; };
class SkeletonEdge class SkeletonEdge {
{
public: public:
SkeletonEdge(const dust3d::Uuid &withId=dust3d::Uuid()) SkeletonEdge(const dust3d::Uuid& withId = dust3d::Uuid())
{ {
id = withId.isNull() ? dust3d::Uuid::createUuid() : withId; id = withId.isNull() ? dust3d::Uuid::createUuid() : withId;
} }
@ -148,8 +147,7 @@ public:
} }
}; };
class SkeletonPart class SkeletonPart {
{
public: public:
dust3d::Uuid id; dust3d::Uuid id;
QString name; QString name;
@ -180,30 +178,30 @@ public:
float hollowThickness; float hollowThickness;
bool countershaded; bool countershaded;
bool smooth; bool smooth;
SkeletonPart(const dust3d::Uuid &withId=dust3d::Uuid()) : SkeletonPart(const dust3d::Uuid& withId = dust3d::Uuid())
visible(true), : visible(true)
locked(false), , locked(false)
subdived(false), , subdived(false)
disabled(false), , disabled(false)
xMirrored(false), , xMirrored(false)
base(dust3d::PartBase::Average), , base(dust3d::PartBase::Average)
deformThickness(1.0), , deformThickness(1.0)
deformWidth(1.0), , deformWidth(1.0)
deformUnified(false), , deformUnified(false)
rounded(false), , rounded(false)
chamfered(false), , chamfered(false)
color(Qt::white), , color(Qt::white)
hasColor(false), , hasColor(false)
dirty(true), , dirty(true)
cutRotation(0.0), , cutRotation(0.0)
cutFace(dust3d::CutFace::Quad), , cutFace(dust3d::CutFace::Quad)
target(dust3d::PartTarget::Model), , target(dust3d::PartTarget::Model)
colorSolubility(0.0), , colorSolubility(0.0)
metalness(0.0), , metalness(0.0)
roughness(1.0), , roughness(1.0)
hollowThickness(0.0), , hollowThickness(0.0)
countershaded(false), , countershaded(false)
smooth(false) , smooth(false)
{ {
id = withId.isNull() ? dust3d::Uuid::createUuid() : withId; id = withId.isNull() ? dust3d::Uuid::createUuid() : withId;
} }
@ -296,7 +294,7 @@ public:
cutFace = face; cutFace = face;
cutFaceLinkedId = dust3d::Uuid(); cutFaceLinkedId = dust3d::Uuid();
} }
void setCutFaceLinkedId(const dust3d::Uuid &linkedId) void setCutFaceLinkedId(const dust3d::Uuid& linkedId)
{ {
if (linkedId.isNull()) { if (linkedId.isNull()) {
setCutFace(dust3d::CutFace::Quad); setCutFace(dust3d::CutFace::Quad);
@ -353,7 +351,7 @@ public:
{ {
return visible && !disabled; return visible && !disabled;
} }
void copyAttributes(const SkeletonPart &other) void copyAttributes(const SkeletonPart& other)
{ {
visible = other.visible; visible = other.visible;
locked = other.locked; locked = other.locked;
@ -382,12 +380,12 @@ public:
smooth = other.smooth; smooth = other.smooth;
hollowThickness = other.hollowThickness; hollowThickness = other.hollowThickness;
} }
private: private:
Q_DISABLE_COPY(SkeletonPart); Q_DISABLE_COPY(SkeletonPart);
}; };
enum class SkeletonDocumentEditMode enum class SkeletonDocumentEditMode {
{
Add = 0, Add = 0,
Select, Select,
Paint, Paint,
@ -396,20 +394,18 @@ enum class SkeletonDocumentEditMode
ZoomOut ZoomOut
}; };
enum class SkeletonProfile enum class SkeletonProfile {
{
Unknown = 0, Unknown = 0,
Main, Main,
Side Side
}; };
class SkeletonComponent class SkeletonComponent {
{
public: public:
SkeletonComponent() SkeletonComponent()
{ {
} }
SkeletonComponent(const dust3d::Uuid &withId, const QString &linkData=QString(), const QString &linkDataType=QString()) SkeletonComponent(const dust3d::Uuid& withId, const QString& linkData = QString(), const QString& linkDataType = QString())
{ {
id = withId.isNull() ? dust3d::Uuid::createUuid() : withId; id = withId.isNull() ? dust3d::Uuid::createUuid() : withId;
if (!linkData.isEmpty()) { if (!linkData.isEmpty()) {
@ -445,13 +441,13 @@ public:
m_childrenIdSet.insert(childId); m_childrenIdSet.insert(childId);
childrenIds.push_back(childId); childrenIds.push_back(childId);
} }
void replaceChildWithOthers(const dust3d::Uuid &childId, const std::vector<dust3d::Uuid> &others) void replaceChildWithOthers(const dust3d::Uuid& childId, const std::vector<dust3d::Uuid>& others)
{ {
if (m_childrenIdSet.find(childId) == m_childrenIdSet.end()) if (m_childrenIdSet.find(childId) == m_childrenIdSet.end())
return; return;
m_childrenIdSet.erase(childId); m_childrenIdSet.erase(childId);
std::vector<dust3d::Uuid> candidates; std::vector<dust3d::Uuid> candidates;
for (const auto &it: others) { for (const auto& it : others) {
if (m_childrenIdSet.find(it) == m_childrenIdSet.end()) { if (m_childrenIdSet.find(it) == m_childrenIdSet.end()) {
m_childrenIdSet.insert(it); m_childrenIdSet.insert(it);
candidates.emplace_back(it); candidates.emplace_back(it);
@ -500,7 +496,7 @@ public:
if (it == childrenIds.end()) { if (it == childrenIds.end()) {
return; return;
} }
auto index = std::distance(childrenIds.begin(), it); auto index = std::distance(childrenIds.begin(), it);
if (index == 0) if (index == 0)
return; return;
@ -512,7 +508,7 @@ public:
if (it == childrenIds.end()) { if (it == childrenIds.end()) {
return; return;
} }
auto index = std::distance(childrenIds.begin(), it); auto index = std::distance(childrenIds.begin(), it);
if (index == (int)childrenIds.size() - 1) if (index == (int)childrenIds.size() - 1)
return; return;
@ -524,7 +520,7 @@ public:
if (it == childrenIds.end()) { if (it == childrenIds.end()) {
return; return;
} }
auto index = std::distance(childrenIds.begin(), it); auto index = std::distance(childrenIds.begin(), it);
if (index == 0) if (index == 0)
return; return;
@ -537,7 +533,7 @@ public:
if (it == childrenIds.end()) { if (it == childrenIds.end()) {
return; return;
} }
auto index = std::distance(childrenIds.begin(), it); auto index = std::distance(childrenIds.begin(), it);
if (index == (int)childrenIds.size() - 1) if (index == (int)childrenIds.size() - 1)
return; return;
@ -549,19 +545,19 @@ public:
m_previewMesh = std::move(mesh); m_previewMesh = std::move(mesh);
isPreviewMeshObsolete = true; isPreviewMeshObsolete = true;
} }
ModelMesh *takePreviewMesh() const ModelMesh* takePreviewMesh() const
{ {
if (nullptr == m_previewMesh) if (nullptr == m_previewMesh)
return nullptr; return nullptr;
return new ModelMesh(*m_previewMesh); return new ModelMesh(*m_previewMesh);
} }
private: private:
std::unique_ptr<ModelMesh> m_previewMesh; std::unique_ptr<ModelMesh> m_previewMesh;
std::set<dust3d::Uuid> m_childrenIdSet; std::set<dust3d::Uuid> m_childrenIdSet;
}; };
class SkeletonDocument : public QObject class SkeletonDocument : public QObject {
{
Q_OBJECT Q_OBJECT
signals: signals:
void partAdded(dust3d::Uuid partId); void partAdded(dust3d::Uuid partId);
@ -576,8 +572,8 @@ signals:
void componentRemoved(dust3d::Uuid componentId); void componentRemoved(dust3d::Uuid componentId);
void componentAdded(dust3d::Uuid componentId); void componentAdded(dust3d::Uuid componentId);
void componentExpandStateChanged(dust3d::Uuid componentId); void componentExpandStateChanged(dust3d::Uuid componentId);
void componentPreviewMeshChanged(const dust3d::Uuid &componentId); void componentPreviewMeshChanged(const dust3d::Uuid& componentId);
void componentPreviewPixmapChanged(const dust3d::Uuid &componentId); void componentPreviewPixmapChanged(const dust3d::Uuid& componentId);
void nodeRemoved(dust3d::Uuid nodeId); void nodeRemoved(dust3d::Uuid nodeId);
void edgeRemoved(dust3d::Uuid edgeId); void edgeRemoved(dust3d::Uuid edgeId);
void nodeRadiusChanged(dust3d::Uuid nodeId); void nodeRadiusChanged(dust3d::Uuid nodeId);
@ -590,6 +586,7 @@ signals:
void ylockStateChanged(); void ylockStateChanged();
void zlockStateChanged(); void zlockStateChanged();
void radiusLockStateChanged(); void radiusLockStateChanged();
public: public:
SkeletonDocumentEditMode editMode = SkeletonDocumentEditMode::Select; SkeletonDocumentEditMode editMode = SkeletonDocumentEditMode::Select;
bool xlocked = false; bool xlocked = false;
@ -604,22 +601,22 @@ public:
std::map<dust3d::Uuid, SkeletonComponent> componentMap; std::map<dust3d::Uuid, SkeletonComponent> componentMap;
SkeletonComponent rootComponent; SkeletonComponent rootComponent;
const SkeletonNode *findNode(dust3d::Uuid nodeId) const; const SkeletonNode* findNode(dust3d::Uuid nodeId) const;
const SkeletonEdge *findEdge(dust3d::Uuid edgeId) const; const SkeletonEdge* findEdge(dust3d::Uuid edgeId) const;
const SkeletonPart *findPart(dust3d::Uuid partId) const; const SkeletonPart* findPart(dust3d::Uuid partId) const;
const SkeletonEdge *findEdgeByNodes(dust3d::Uuid firstNodeId, dust3d::Uuid secondNodeId) const; const SkeletonEdge* findEdgeByNodes(dust3d::Uuid firstNodeId, dust3d::Uuid secondNodeId) const;
void findAllNeighbors(dust3d::Uuid nodeId, std::set<dust3d::Uuid> &neighbors) const; void findAllNeighbors(dust3d::Uuid nodeId, std::set<dust3d::Uuid>& neighbors) const;
bool isNodeConnectable(dust3d::Uuid nodeId) const; bool isNodeConnectable(dust3d::Uuid nodeId) const;
const SkeletonComponent *findComponent(dust3d::Uuid componentId) const; const SkeletonComponent* findComponent(dust3d::Uuid componentId) const;
const SkeletonComponent *findComponentParent(dust3d::Uuid componentId) const; const SkeletonComponent* findComponentParent(dust3d::Uuid componentId) const;
dust3d::Uuid findComponentParentId(dust3d::Uuid componentId) const; dust3d::Uuid findComponentParentId(dust3d::Uuid componentId) const;
void collectComponentDescendantParts(dust3d::Uuid componentId, std::vector<dust3d::Uuid> &partIds) const; void collectComponentDescendantParts(dust3d::Uuid componentId, std::vector<dust3d::Uuid>& partIds) const;
void collectComponentDescendantComponents(dust3d::Uuid componentId, std::vector<dust3d::Uuid> &componentIds) const; void collectComponentDescendantComponents(dust3d::Uuid componentId, std::vector<dust3d::Uuid>& componentIds) const;
void setComponentPreviewMesh(const dust3d::Uuid &componentId, std::unique_ptr<ModelMesh> mesh); void setComponentPreviewMesh(const dust3d::Uuid& componentId, std::unique_ptr<ModelMesh> mesh);
void setComponentPreviewImage(const dust3d::Uuid &componentId, std::unique_ptr<QImage> image); void setComponentPreviewImage(const dust3d::Uuid& componentId, std::unique_ptr<QImage> image);
void resetDirtyFlags(); void resetDirtyFlags();
void markAllDirty(); void markAllDirty();
virtual bool undoable() const = 0; virtual bool undoable() const = 0;
virtual bool redoable() const = 0; virtual bool redoable() const = 0;
virtual bool hasPastableNodesInClipboard() const = 0; virtual bool hasPastableNodesInClipboard() const = 0;
@ -628,31 +625,31 @@ public:
virtual bool isEdgeEditable(dust3d::Uuid edgeId) const = 0; virtual bool isEdgeEditable(dust3d::Uuid edgeId) const = 0;
virtual bool isNodeDeactivated(dust3d::Uuid nodeId) const virtual bool isNodeDeactivated(dust3d::Uuid nodeId) const
{ {
(void) nodeId; (void)nodeId;
return false; return false;
}; };
virtual bool isEdgeDeactivated(dust3d::Uuid edgeId) const virtual bool isEdgeDeactivated(dust3d::Uuid edgeId) const
{ {
(void) edgeId; (void)edgeId;
return false; return false;
}; };
virtual void copyNodes(std::set<dust3d::Uuid> nodeIdSet) const = 0; virtual void copyNodes(std::set<dust3d::Uuid> nodeIdSet) const = 0;
float getOriginX(bool rotated=false) const float getOriginX(bool rotated = false) const
{ {
if (rotated) if (rotated)
return m_originY; return m_originY;
return m_originX; return m_originX;
} }
float getOriginY(bool rotated=false) const float getOriginY(bool rotated = false) const
{ {
if (rotated) if (rotated)
return m_originX; return m_originX;
return m_originY; return m_originY;
} }
float getOriginZ(bool rotated=false) const float getOriginZ(bool rotated = false) const
{ {
(void) rotated; (void)rotated;
return m_originZ; return m_originZ;
} }
void setOriginX(float originX) void setOriginX(float originX)
@ -679,7 +676,7 @@ public:
{ {
m_originZ += originZ; m_originZ += originZ;
} }
public slots: public slots:
virtual void undo() = 0; virtual void undo() = 0;
virtual void redo() = 0; virtual void redo() = 0;
@ -706,8 +703,8 @@ public slots:
void addComponent(dust3d::Uuid parentId); void addComponent(dust3d::Uuid parentId);
void moveComponent(dust3d::Uuid componentId, dust3d::Uuid toParentId); void moveComponent(dust3d::Uuid componentId, dust3d::Uuid toParentId);
void setCurrentCanvasComponentId(dust3d::Uuid componentId); void setCurrentCanvasComponentId(dust3d::Uuid componentId);
void groupComponents(const std::vector<dust3d::Uuid> &componentIds); void groupComponents(const std::vector<dust3d::Uuid>& componentIds);
void ungroupComponent(const dust3d::Uuid &componentId); void ungroupComponent(const dust3d::Uuid& componentId);
void createNewChildComponent(dust3d::Uuid parentComponentId); void createNewChildComponent(dust3d::Uuid parentComponentId);
void setComponentExpandState(dust3d::Uuid componentId, bool expanded); void setComponentExpandState(dust3d::Uuid componentId, bool expanded);
void hideOtherComponents(dust3d::Uuid componentId); void hideOtherComponents(dust3d::Uuid componentId);
@ -723,7 +720,7 @@ public slots:
void showDescendantComponents(dust3d::Uuid componentId); void showDescendantComponents(dust3d::Uuid componentId);
void lockDescendantComponents(dust3d::Uuid componentId); void lockDescendantComponents(dust3d::Uuid componentId);
void unlockDescendantComponents(dust3d::Uuid componentId); void unlockDescendantComponents(dust3d::Uuid componentId);
void setComponentPreviewPixmap(const dust3d::Uuid &componentId, const QPixmap &pixmap); void setComponentPreviewPixmap(const dust3d::Uuid& componentId, const QPixmap& pixmap);
void setPartLockState(dust3d::Uuid partId, bool locked); void setPartLockState(dust3d::Uuid partId, bool locked);
void setPartVisibleState(dust3d::Uuid partId, bool visible); void setPartVisibleState(dust3d::Uuid partId, bool visible);
void setPartDisableState(dust3d::Uuid partId, bool disabled); void setPartDisableState(dust3d::Uuid partId, bool disabled);
@ -737,18 +734,18 @@ public slots:
void setYlockState(bool locked); void setYlockState(bool locked);
void setZlockState(bool locked); void setZlockState(bool locked);
void setRadiusLockState(bool locked); void setRadiusLockState(bool locked);
private: private:
float m_originX = 0; float m_originX = 0;
float m_originY = 0; float m_originY = 0;
float m_originZ = 0; float m_originZ = 0;
dust3d::Uuid m_currentCanvasComponentId; dust3d::Uuid m_currentCanvasComponentId;
bool m_allPositionRelatedLocksEnabled = true; bool m_allPositionRelatedLocksEnabled = true;
void splitPartByNode(std::vector<std::vector<dust3d::Uuid>> *groups, dust3d::Uuid nodeId); void splitPartByNode(std::vector<std::vector<dust3d::Uuid>>* groups, dust3d::Uuid nodeId);
void joinNodeAndNeiborsToGroup(std::vector<dust3d::Uuid> *group, dust3d::Uuid nodeId, std::set<dust3d::Uuid> *visitMap, dust3d::Uuid noUseEdgeId=dust3d::Uuid()); void joinNodeAndNeiborsToGroup(std::vector<dust3d::Uuid>* group, dust3d::Uuid nodeId, std::set<dust3d::Uuid>* visitMap, dust3d::Uuid noUseEdgeId = dust3d::Uuid());
void splitPartByEdge(std::vector<std::vector<dust3d::Uuid>> *groups, dust3d::Uuid edgeId); void splitPartByEdge(std::vector<std::vector<dust3d::Uuid>>* groups, dust3d::Uuid edgeId);
void removePartDontCareComponent(dust3d::Uuid partId); void removePartDontCareComponent(dust3d::Uuid partId);
void addPartToComponent(dust3d::Uuid partId, dust3d::Uuid componentId); void addPartToComponent(dust3d::Uuid partId, dust3d::Uuid componentId);
bool isDescendantComponent(dust3d::Uuid componentId, dust3d::Uuid suspiciousId); bool isDescendantComponent(dust3d::Uuid componentId, dust3d::Uuid suspiciousId);

File diff suppressed because it is too large Load Diff

View File

@ -1,32 +1,31 @@
#ifndef DUST3D_APPLICATION_SKELETON_GRAPHICS_VIEW_H_ #ifndef DUST3D_APPLICATION_SKELETON_GRAPHICS_VIEW_H_
#define DUST3D_APPLICATION_SKELETON_GRAPHICS_VIEW_H_ #define DUST3D_APPLICATION_SKELETON_GRAPHICS_VIEW_H_
#include <map> #include "model_widget.h"
#include <QMouseEvent> #include "skeleton_document.h"
#include <QKeyEvent> #include "skeleton_ik_mover.h"
#include "theme.h"
#include "turnaround_loader.h"
#include <QGraphicsEllipseItem> #include <QGraphicsEllipseItem>
#include <QGraphicsLineItem> #include <QGraphicsLineItem>
#include <QGraphicsView>
#include <QGraphicsPixmapItem> #include <QGraphicsPixmapItem>
#include <QGraphicsPolygonItem> #include <QGraphicsPolygonItem>
#include <QGraphicsView>
#include <QKeyEvent>
#include <QMouseEvent>
#include <QThread> #include <QThread>
#include <cmath>
#include <set>
#include <QTimer> #include <QTimer>
#include "skeleton_document.h" #include <cmath>
#include "turnaround_loader.h" #include <map>
#include "theme.h" #include <set>
#include "skeleton_ik_mover.h"
#include "model_widget.h"
class SkeletonGraphicsOriginItem : public QGraphicsPolygonItem class SkeletonGraphicsOriginItem : public QGraphicsPolygonItem {
{
public: public:
SkeletonGraphicsOriginItem(SkeletonProfile profile=SkeletonProfile::Unknown) : SkeletonGraphicsOriginItem(SkeletonProfile profile = SkeletonProfile::Unknown)
m_profile(profile), : m_profile(profile)
m_hovered(false), , m_hovered(false)
m_checked(false), , m_checked(false)
m_rotated(false) , m_rotated(false)
{ {
setData(0, "origin"); setData(0, "origin");
} }
@ -37,9 +36,8 @@ public:
void updateAppearance() void updateAppearance()
{ {
QColor color = Theme::white; QColor color = Theme::white;
switch (m_profile) switch (m_profile) {
{
case SkeletonProfile::Unknown: case SkeletonProfile::Unknown:
break; break;
case SkeletonProfile::Main: case SkeletonProfile::Main:
@ -49,13 +47,13 @@ public:
color = Theme::green; color = Theme::green;
break; break;
} }
QColor penColor = color; QColor penColor = color;
penColor.setAlphaF(m_checked ? Theme::checkedAlpha : Theme::normalAlpha); penColor.setAlphaF(m_checked ? Theme::checkedAlpha : Theme::normalAlpha);
QPen pen(penColor); QPen pen(penColor);
pen.setWidth(0); pen.setWidth(0);
setPen(pen); setPen(pen);
QColor brushColor = color; QColor brushColor = color;
brushColor.setAlphaF((m_checked || m_hovered) ? Theme::checkedAlpha : Theme::normalAlpha); brushColor.setAlphaF((m_checked || m_hovered) ? Theme::checkedAlpha : Theme::normalAlpha);
QBrush brush(brushColor); QBrush brush(brushColor);
@ -99,6 +97,7 @@ public:
{ {
return m_hovered; return m_hovered;
} }
private: private:
SkeletonProfile m_profile; SkeletonProfile m_profile;
bool m_hovered; bool m_hovered;
@ -107,8 +106,7 @@ private:
bool m_rotated; bool m_rotated;
}; };
class SkeletonGraphicsSelectionItem : public QGraphicsRectItem class SkeletonGraphicsSelectionItem : public QGraphicsRectItem {
{
public: public:
SkeletonGraphicsSelectionItem() SkeletonGraphicsSelectionItem()
{ {
@ -124,16 +122,15 @@ public:
} }
}; };
class SkeletonGraphicsNodeItem : public QGraphicsEllipseItem class SkeletonGraphicsNodeItem : public QGraphicsEllipseItem {
{
public: public:
SkeletonGraphicsNodeItem(SkeletonProfile profile=SkeletonProfile::Unknown) : SkeletonGraphicsNodeItem(SkeletonProfile profile = SkeletonProfile::Unknown)
m_profile(profile), : m_profile(profile)
m_hovered(false), , m_hovered(false)
m_checked(false), , m_checked(false)
m_markColor(Qt::transparent), , m_markColor(Qt::transparent)
m_deactivated(false), , m_deactivated(false)
m_rotated(false) , m_rotated(false)
{ {
setData(0, "node"); setData(0, "node");
setRadius(32); setRadius(32);
@ -145,10 +142,9 @@ public:
void updateAppearance() void updateAppearance()
{ {
QColor color = Qt::gray; QColor color = Qt::gray;
if (!m_deactivated) { if (!m_deactivated) {
switch (m_profile) switch (m_profile) {
{
case SkeletonProfile::Unknown: case SkeletonProfile::Unknown:
break; break;
case SkeletonProfile::Main: case SkeletonProfile::Main:
@ -159,13 +155,13 @@ public:
break; break;
} }
} }
QColor penColor = color; QColor penColor = color;
penColor.setAlphaF((m_checked || m_hovered) ? Theme::checkedAlpha : Theme::normalAlpha); penColor.setAlphaF((m_checked || m_hovered) ? Theme::checkedAlpha : Theme::normalAlpha);
QPen pen(penColor); QPen pen(penColor);
pen.setWidth(0); pen.setWidth(0);
setPen(pen); setPen(pen);
QColor brushColor; QColor brushColor;
Qt::BrushStyle style; Qt::BrushStyle style;
if (m_markColor == Qt::transparent) { if (m_markColor == Qt::transparent) {
@ -253,6 +249,7 @@ public:
{ {
return m_hovered; return m_hovered;
} }
private: private:
dust3d::Uuid m_uuid; dust3d::Uuid m_uuid;
SkeletonProfile m_profile; SkeletonProfile m_profile;
@ -263,17 +260,16 @@ private:
bool m_rotated; bool m_rotated;
}; };
class SkeletonGraphicsEdgeItem : public QGraphicsPolygonItem class SkeletonGraphicsEdgeItem : public QGraphicsPolygonItem {
{
public: public:
SkeletonGraphicsEdgeItem() : SkeletonGraphicsEdgeItem()
m_firstItem(nullptr), : m_firstItem(nullptr)
m_secondItem(nullptr), , m_secondItem(nullptr)
m_hovered(false), , m_hovered(false)
m_checked(false), , m_checked(false)
m_profile(SkeletonProfile::Unknown), , m_profile(SkeletonProfile::Unknown)
m_deactivated(false), , m_deactivated(false)
m_rotated(false) , m_rotated(false)
{ {
setData(0, "edge"); setData(0, "edge");
} }
@ -281,17 +277,17 @@ public:
{ {
m_rotated = rotated; m_rotated = rotated;
} }
void setEndpoints(SkeletonGraphicsNodeItem *first, SkeletonGraphicsNodeItem *second) void setEndpoints(SkeletonGraphicsNodeItem* first, SkeletonGraphicsNodeItem* second)
{ {
m_firstItem = first; m_firstItem = first;
m_secondItem = second; m_secondItem = second;
updateAppearance(); updateAppearance();
} }
SkeletonGraphicsNodeItem *firstItem() SkeletonGraphicsNodeItem* firstItem()
{ {
return m_firstItem; return m_firstItem;
} }
SkeletonGraphicsNodeItem *secondItem() SkeletonGraphicsNodeItem* secondItem()
{ {
return m_secondItem; return m_secondItem;
} }
@ -299,11 +295,11 @@ public:
{ {
if (nullptr == m_firstItem || nullptr == m_secondItem) if (nullptr == m_firstItem || nullptr == m_secondItem)
return; return;
m_profile = m_firstItem->profile(); m_profile = m_firstItem->profile();
QLineF line(m_firstItem->origin(), m_secondItem->origin()); QLineF line(m_firstItem->origin(), m_secondItem->origin());
QPolygonF polygon; QPolygonF polygon;
float radAngle = line.angle() * M_PI / 180; float radAngle = line.angle() * M_PI / 180;
float dx = 2 * sin(radAngle); float dx = 2 * sin(radAngle);
@ -313,12 +309,11 @@ public:
//polygon << line.p1() + offset1 << line.p1() + offset2 << line.p2() + offset2 << line.p2() + offset1; //polygon << line.p1() + offset1 << line.p1() + offset2 << line.p2() + offset2 << line.p2() + offset1;
polygon << line.p1() + offset1 << line.p1() + offset2 << line.p2(); polygon << line.p1() + offset1 << line.p1() + offset2 << line.p2();
setPolygon(polygon); setPolygon(polygon);
QColor color = Qt::gray; QColor color = Qt::gray;
if (!m_deactivated) { if (!m_deactivated) {
switch (m_firstItem->profile()) switch (m_firstItem->profile()) {
{
case SkeletonProfile::Unknown: case SkeletonProfile::Unknown:
break; break;
case SkeletonProfile::Main: case SkeletonProfile::Main:
@ -329,7 +324,7 @@ public:
break; break;
} }
} }
QColor penColor = color; QColor penColor = color;
penColor.setAlphaF((m_checked || m_hovered) ? Theme::checkedAlpha : Theme::normalAlpha); penColor.setAlphaF((m_checked || m_hovered) ? Theme::checkedAlpha : Theme::normalAlpha);
QPen pen(penColor); QPen pen(penColor);
@ -380,10 +375,11 @@ public:
{ {
return m_hovered; return m_hovered;
} }
private: private:
dust3d::Uuid m_uuid; dust3d::Uuid m_uuid;
SkeletonGraphicsNodeItem *m_firstItem; SkeletonGraphicsNodeItem* m_firstItem;
SkeletonGraphicsNodeItem *m_secondItem; SkeletonGraphicsNodeItem* m_secondItem;
QPolygonF m_selectionPolygon; QPolygonF m_selectionPolygon;
bool m_hovered; bool m_hovered;
bool m_checked; bool m_checked;
@ -392,8 +388,7 @@ private:
bool m_rotated; bool m_rotated;
}; };
class SkeletonGraphicsWidget : public QGraphicsView class SkeletonGraphicsWidget : public QGraphicsView {
{
Q_OBJECT Q_OBJECT
public: public:
~SkeletonGraphicsWidget(); ~SkeletonGraphicsWidget();
@ -445,43 +440,45 @@ signals:
void shortcutToggleFlatShading(); void shortcutToggleFlatShading();
void shortcutToggleRotation(); void shortcutToggleRotation();
void loadedTurnaroundImageChanged(); void loadedTurnaroundImageChanged();
public: public:
SkeletonGraphicsWidget(const SkeletonDocument *document); SkeletonGraphicsWidget(const SkeletonDocument* document);
std::map<dust3d::Uuid, std::pair<SkeletonGraphicsNodeItem *, SkeletonGraphicsNodeItem *>> nodeItemMap; std::map<dust3d::Uuid, std::pair<SkeletonGraphicsNodeItem*, SkeletonGraphicsNodeItem*>> nodeItemMap;
std::map<dust3d::Uuid, std::pair<SkeletonGraphicsEdgeItem *, SkeletonGraphicsEdgeItem *>> edgeItemMap; std::map<dust3d::Uuid, std::pair<SkeletonGraphicsEdgeItem*, SkeletonGraphicsEdgeItem*>> edgeItemMap;
bool mouseMove(QMouseEvent *event); bool mouseMove(QMouseEvent* event);
bool wheel(QWheelEvent *event); bool wheel(QWheelEvent* event);
bool mouseRelease(QMouseEvent *event); bool mouseRelease(QMouseEvent* event);
bool mousePress(QMouseEvent *event); bool mousePress(QMouseEvent* event);
bool mouseDoubleClick(QMouseEvent *event); bool mouseDoubleClick(QMouseEvent* event);
bool keyPress(QKeyEvent *event); bool keyPress(QKeyEvent* event);
bool keyRelease(QKeyEvent *event); bool keyRelease(QKeyEvent* event);
bool checkSkeletonItem(QGraphicsItem *item, bool checked); bool checkSkeletonItem(QGraphicsItem* item, bool checked);
dust3d::Uuid querySkeletonItemPartId(QGraphicsItem *item); dust3d::Uuid querySkeletonItemPartId(QGraphicsItem* item);
static SkeletonProfile readSkeletonItemProfile(QGraphicsItem *item); static SkeletonProfile readSkeletonItemProfile(QGraphicsItem* item);
void getOtherProfileNodeItems(const std::set<SkeletonGraphicsNodeItem *> &nodeItemSet, void getOtherProfileNodeItems(const std::set<SkeletonGraphicsNodeItem*>& nodeItemSet,
std::set<SkeletonGraphicsNodeItem *> *otherProfileNodeItemSet); std::set<SkeletonGraphicsNodeItem*>* otherProfileNodeItemSet);
void readMergedSkeletonNodeSetFromRangeSelection(std::set<SkeletonGraphicsNodeItem *> *nodeItemSet); void readMergedSkeletonNodeSetFromRangeSelection(std::set<SkeletonGraphicsNodeItem*>* nodeItemSet);
void readSkeletonNodeAndEdgeIdSetFromRangeSelection(std::set<dust3d::Uuid> *nodeIdSet, std::set<dust3d::Uuid> *edgeIdSet=nullptr); void readSkeletonNodeAndEdgeIdSetFromRangeSelection(std::set<dust3d::Uuid>* nodeIdSet, std::set<dust3d::Uuid>* edgeIdSet = nullptr);
bool readSkeletonNodeAndAnyEdgeOfNodeFromRangeSelection(SkeletonGraphicsNodeItem **nodeItem, SkeletonGraphicsEdgeItem **edgeItem); bool readSkeletonNodeAndAnyEdgeOfNodeFromRangeSelection(SkeletonGraphicsNodeItem** nodeItem, SkeletonGraphicsEdgeItem** edgeItem);
bool hasSelection(); bool hasSelection();
bool hasItems(); bool hasItems();
bool hasMultipleSelection(); bool hasMultipleSelection();
bool hasEdgeSelection(); bool hasEdgeSelection();
bool hasNodeSelection(); bool hasNodeSelection();
bool hasTwoDisconnectedNodesSelection(); bool hasTwoDisconnectedNodesSelection();
void setModelWidget(ModelWidget *modelWidget); void setModelWidget(ModelWidget* modelWidget);
bool inputWheelEventFromOtherWidget(QWheelEvent *event); bool inputWheelEventFromOtherWidget(QWheelEvent* event);
bool rotated(); bool rotated();
const QImage *loadedTurnaroundImage() const; const QImage* loadedTurnaroundImage() const;
protected: protected:
void mouseMoveEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent* event) override;
void wheelEvent(QWheelEvent *event) override; void wheelEvent(QWheelEvent* event) override;
void mouseReleaseEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent* event) override;
void mousePressEvent(QMouseEvent *event) override; void mousePressEvent(QMouseEvent* event) override;
void mouseDoubleClickEvent(QMouseEvent *event) override; void mouseDoubleClickEvent(QMouseEvent* event) override;
void keyPressEvent(QKeyEvent *event) override; void keyPressEvent(QKeyEvent* event) override;
void keyReleaseEvent(QKeyEvent *event) override; void keyReleaseEvent(QKeyEvent* event) override;
public slots: public slots:
void nodeAdded(dust3d::Uuid nodeId); void nodeAdded(dust3d::Uuid nodeId);
void edgeAdded(dust3d::Uuid edgeId); void edgeAdded(dust3d::Uuid edgeId);
@ -495,7 +492,7 @@ public slots:
void editModeChanged(); void editModeChanged();
void updateCursor(); void updateCursor();
void partVisibleStateChanged(dust3d::Uuid partId); void partVisibleStateChanged(dust3d::Uuid partId);
void showContextMenu(const QPoint &pos); void showContextMenu(const QPoint& pos);
void deleteSelected(); void deleteSelected();
void selectAll(); void selectAll();
void unselectAll(); void unselectAll();
@ -577,8 +574,9 @@ public slots:
void shortcutEscape(); void shortcutEscape();
private slots: private slots:
void turnaroundImageReady(); void turnaroundImageReady();
private: private:
QPointF mouseEventScenePos(QMouseEvent *event); QPointF mouseEventScenePos(QMouseEvent* event);
QPointF scenePosToUnified(QPointF pos); QPointF scenePosToUnified(QPointF pos);
QPointF scenePosFromUnified(QPointF pos); QPointF scenePosFromUnified(QPointF pos);
float sceneRadiusToUnified(float radius); float sceneRadiusToUnified(float radius);
@ -587,56 +585,57 @@ private:
void updateItems(); void updateItems();
void checkRangeSelection(); void checkRangeSelection();
void clearRangeSelection(); void clearRangeSelection();
void removeItem(QGraphicsItem *item); void removeItem(QGraphicsItem* item);
QVector2D centerOfNodeItemSet(const std::set<SkeletonGraphicsNodeItem *> &set); QVector2D centerOfNodeItemSet(const std::set<SkeletonGraphicsNodeItem*>& set);
bool isSingleNodeSelected(); bool isSingleNodeSelected();
void addItemToRangeSelection(QGraphicsItem *item); void addItemToRangeSelection(QGraphicsItem* item);
void removeItemFromRangeSelection(QGraphicsItem *item); void removeItemFromRangeSelection(QGraphicsItem* item);
void hoverPart(dust3d::Uuid partId); void hoverPart(dust3d::Uuid partId);
void switchProfileOnRangeSelection(); void switchProfileOnRangeSelection();
void setItemHoveredOnAllProfiles(QGraphicsItem *item, bool hovered); void setItemHoveredOnAllProfiles(QGraphicsItem* item, bool hovered);
void alignSelectedToGlobal(bool alignToVerticalCenter, bool alignToHorizontalCenter); void alignSelectedToGlobal(bool alignToVerticalCenter, bool alignToHorizontalCenter);
void alignSelectedToLocal(bool alignToVerticalCenter, bool alignToHorizontalCenter); void alignSelectedToLocal(bool alignToVerticalCenter, bool alignToHorizontalCenter);
void rotateItems(const std::set<SkeletonGraphicsNodeItem *> &nodeItems, int degree, QVector2D center); void rotateItems(const std::set<SkeletonGraphicsNodeItem*>& nodeItems, int degree, QVector2D center);
void rotateAllSideProfile(int degree); void rotateAllSideProfile(int degree);
bool isFloatEqual(float a, float b); bool isFloatEqual(float a, float b);
private: private:
const SkeletonDocument *m_document = nullptr; const SkeletonDocument* m_document = nullptr;
QGraphicsPixmapItem *m_backgroundItem = nullptr; QGraphicsPixmapItem* m_backgroundItem = nullptr;
bool m_turnaroundChanged = false; bool m_turnaroundChanged = false;
TurnaroundLoader *m_turnaroundLoader = nullptr; TurnaroundLoader* m_turnaroundLoader = nullptr;
bool m_dragStarted = false; bool m_dragStarted = false;
bool m_moveStarted = false; bool m_moveStarted = false;
SkeletonGraphicsNodeItem *m_cursorNodeItem = nullptr; SkeletonGraphicsNodeItem* m_cursorNodeItem = nullptr;
SkeletonGraphicsEdgeItem *m_cursorEdgeItem = nullptr; SkeletonGraphicsEdgeItem* m_cursorEdgeItem = nullptr;
SkeletonGraphicsNodeItem *m_addFromNodeItem = nullptr; SkeletonGraphicsNodeItem* m_addFromNodeItem = nullptr;
SkeletonGraphicsNodeItem *m_hoveredNodeItem = nullptr; SkeletonGraphicsNodeItem* m_hoveredNodeItem = nullptr;
SkeletonGraphicsEdgeItem *m_hoveredEdgeItem = nullptr; SkeletonGraphicsEdgeItem* m_hoveredEdgeItem = nullptr;
float m_lastAddedX = false; float m_lastAddedX = false;
float m_lastAddedY = false; float m_lastAddedY = false;
float m_lastAddedZ = false; float m_lastAddedZ = false;
SkeletonGraphicsSelectionItem *m_selectionItem = nullptr; SkeletonGraphicsSelectionItem* m_selectionItem = nullptr;
bool m_rangeSelectionStarted = false; bool m_rangeSelectionStarted = false;
bool m_mouseEventFromSelf = false; bool m_mouseEventFromSelf = false;
bool m_moveHappened = false; bool m_moveHappened = false;
int m_lastRot = 0; int m_lastRot = 0;
SkeletonGraphicsOriginItem *m_mainOriginItem = nullptr; SkeletonGraphicsOriginItem* m_mainOriginItem = nullptr;
SkeletonGraphicsOriginItem *m_sideOriginItem = nullptr; SkeletonGraphicsOriginItem* m_sideOriginItem = nullptr;
SkeletonGraphicsOriginItem *m_hoveredOriginItem = nullptr; SkeletonGraphicsOriginItem* m_hoveredOriginItem = nullptr;
SkeletonGraphicsOriginItem *m_checkedOriginItem = nullptr; SkeletonGraphicsOriginItem* m_checkedOriginItem = nullptr;
unsigned long long m_ikMoveUpdateVersion = 0; unsigned long long m_ikMoveUpdateVersion = 0;
SkeletonIkMover *m_ikMover = nullptr; SkeletonIkMover* m_ikMover = nullptr;
QTimer *m_deferredRemoveTimer = nullptr; QTimer* m_deferredRemoveTimer = nullptr;
bool m_eventForwardingToModelWidget = false; bool m_eventForwardingToModelWidget = false;
ModelWidget *m_modelWidget = nullptr; ModelWidget* m_modelWidget = nullptr;
bool m_inTempDragMode = false; bool m_inTempDragMode = false;
SkeletonDocumentEditMode m_modeBeforeEnterTempDragMode = SkeletonDocumentEditMode::Select; SkeletonDocumentEditMode m_modeBeforeEnterTempDragMode = SkeletonDocumentEditMode::Select;
float m_turnaroundOpacity = 0.25f; float m_turnaroundOpacity = 0.25f;
bool m_rotated = false; bool m_rotated = false;
QImage *m_backgroundImage = nullptr; QImage* m_backgroundImage = nullptr;
QVector3D m_ikMoveTarget; QVector3D m_ikMoveTarget;
dust3d::Uuid m_ikMoveEndEffectorId; dust3d::Uuid m_ikMoveEndEffectorId;
std::set<QGraphicsItem *> m_rangeSelectionSet; std::set<QGraphicsItem*> m_rangeSelectionSet;
QPoint m_lastGlobalPos; QPoint m_lastGlobalPos;
QPointF m_lastScenePos; QPointF m_lastScenePos;
QPointF m_rangeSelectionStartPos; QPointF m_rangeSelectionStartPos;
@ -645,27 +644,28 @@ private:
std::set<dust3d::Uuid> m_deferredRemoveEdgeIds; std::set<dust3d::Uuid> m_deferredRemoveEdgeIds;
}; };
class SkeletonGraphicsContainerWidget : public QWidget class SkeletonGraphicsContainerWidget : public QWidget {
{
Q_OBJECT Q_OBJECT
signals: signals:
void containerSizeChanged(QSize size); void containerSizeChanged(QSize size);
public: public:
SkeletonGraphicsContainerWidget() : SkeletonGraphicsContainerWidget()
m_graphicsWidget(nullptr) : m_graphicsWidget(nullptr)
{ {
} }
void resizeEvent(QResizeEvent *event) override void resizeEvent(QResizeEvent* event) override
{ {
if (m_graphicsWidget && m_graphicsWidget->size() != event->size()) if (m_graphicsWidget && m_graphicsWidget->size() != event->size())
emit containerSizeChanged(event->size()); emit containerSizeChanged(event->size());
} }
void setGraphicsWidget(SkeletonGraphicsWidget *graphicsWidget) void setGraphicsWidget(SkeletonGraphicsWidget* graphicsWidget)
{ {
m_graphicsWidget = graphicsWidget; m_graphicsWidget = graphicsWidget;
} }
private: private:
SkeletonGraphicsWidget *m_graphicsWidget; SkeletonGraphicsWidget* m_graphicsWidget;
}; };
#endif #endif

View File

@ -1,6 +1,6 @@
#include <QGuiApplication>
#include "skeleton_ik_mover.h" #include "skeleton_ik_mover.h"
#include "ccd_ik_resolver.h" #include "ccd_ik_resolver.h"
#include <QGuiApplication>
SkeletonIkMover::SkeletonIkMover() SkeletonIkMover::SkeletonIkMover()
{ {
@ -10,7 +10,7 @@ SkeletonIkMover::~SkeletonIkMover()
{ {
} }
void SkeletonIkMover::setTarget(const QVector3D &target) void SkeletonIkMover::setTarget(const QVector3D& target)
{ {
m_target = target; m_target = target;
} }
@ -33,7 +33,7 @@ void SkeletonIkMover::addNode(dust3d::Uuid id, QVector3D position)
m_ikNodes.push_back(ikNode); m_ikNodes.push_back(ikNode);
} }
const std::vector<SkeletonIkNode> &SkeletonIkMover::ikNodes() const std::vector<SkeletonIkNode>& SkeletonIkMover::ikNodes()
{ {
return m_ikNodes; return m_ikNodes;
} }
@ -41,7 +41,7 @@ const std::vector<SkeletonIkNode> &SkeletonIkMover::ikNodes()
void SkeletonIkMover::process() void SkeletonIkMover::process()
{ {
resolve(); resolve();
emit finished(); emit finished();
} }

View File

@ -2,34 +2,34 @@
#define DUST3D_APPLICATION_SKELETON_IK_MOVER_H_ #define DUST3D_APPLICATION_SKELETON_IK_MOVER_H_
#include <QObject> #include <QObject>
#include <vector>
#include <QVector3D> #include <QVector3D>
#include <dust3d/base/uuid.h> #include <dust3d/base/uuid.h>
#include <vector>
struct SkeletonIkNode struct SkeletonIkNode {
{
dust3d::Uuid id; dust3d::Uuid id;
QVector3D position; QVector3D position;
QVector3D newPosition; QVector3D newPosition;
}; };
class SkeletonIkMover : public QObject class SkeletonIkMover : public QObject {
{
Q_OBJECT Q_OBJECT
public: public:
SkeletonIkMover(); SkeletonIkMover();
~SkeletonIkMover(); ~SkeletonIkMover();
void setTarget(const QVector3D &target); void setTarget(const QVector3D& target);
void setUpdateVersion(unsigned long long version); void setUpdateVersion(unsigned long long version);
unsigned long long getUpdateVersion(); unsigned long long getUpdateVersion();
void addNode(dust3d::Uuid id, QVector3D position); void addNode(dust3d::Uuid id, QVector3D position);
const std::vector<SkeletonIkNode> &ikNodes(); const std::vector<SkeletonIkNode>& ikNodes();
signals: signals:
void finished(); void finished();
public slots: public slots:
void process(); void process();
private: private:
void resolve(); void resolve();
private: private:
unsigned long long m_updateVersion = 0; unsigned long long m_updateVersion = 0;
std::vector<SkeletonIkNode> m_ikNodes; std::vector<SkeletonIkNode> m_ikNodes;

View File

@ -1,8 +1,8 @@
#include "spinnable_toolbar_icon.h" #include "spinnable_toolbar_icon.h"
#include "theme.h" #include "theme.h"
SpinnableToolbarIcon::SpinnableToolbarIcon(QWidget *parent) : SpinnableToolbarIcon::SpinnableToolbarIcon(QWidget* parent)
QWidget(parent) : QWidget(parent)
{ {
setFixedSize(Theme::toolIconSize, Theme::toolIconSize); setFixedSize(Theme::toolIconSize, Theme::toolIconSize);

View File

@ -1,18 +1,18 @@
#ifndef DUST3D_APPLICATION_SPINNABLE_TOOLBAR_ICON_H_ #ifndef DUST3D_APPLICATION_SPINNABLE_TOOLBAR_ICON_H_
#define DUST3D_APPLICATION_SPINNABLE_TOOLBAR_ICON_H_ #define DUST3D_APPLICATION_SPINNABLE_TOOLBAR_ICON_H_
#include <QWidget>
#include "waitingspinnerwidget.h"
#include "toolbar_button.h" #include "toolbar_button.h"
#include "waitingspinnerwidget.h"
#include <QWidget>
class SpinnableToolbarIcon : public QWidget class SpinnableToolbarIcon : public QWidget {
{
public: public:
SpinnableToolbarIcon(QWidget *parent=nullptr); SpinnableToolbarIcon(QWidget* parent = nullptr);
void showSpinner(bool showSpinner=true); void showSpinner(bool showSpinner = true);
bool isSpinning(); bool isSpinning();
private: private:
WaitingSpinnerWidget *m_spinner = nullptr; WaitingSpinnerWidget* m_spinner = nullptr;
}; };
#endif #endif

View File

@ -1,19 +1,19 @@
#include <QPainter>
#include <QGuiApplication>
#include <QRegion>
#include <QPolygon>
#include <QElapsedTimer>
#include <QRadialGradient>
#include <dust3d/base/texture_type.h>
#include "texture_generator.h" #include "texture_generator.h"
#include "theme.h"
#include "material.h"
#include "debug.h" #include "debug.h"
#include "material.h"
#include "theme.h"
#include <QElapsedTimer>
#include <QGuiApplication>
#include <QPainter>
#include <QPolygon>
#include <QRadialGradient>
#include <QRegion>
#include <dust3d/base/texture_type.h>
QColor TextureGenerator::m_defaultTextureColor = Qt::transparent; QColor TextureGenerator::m_defaultTextureColor = Qt::transparent;
TextureGenerator::TextureGenerator(const dust3d::Object &object, dust3d::Snapshot *snapshot) : TextureGenerator::TextureGenerator(const dust3d::Object& object, dust3d::Snapshot* snapshot)
m_snapshot(snapshot) : m_snapshot(snapshot)
{ {
m_object = new dust3d::Object(); m_object = new dust3d::Object();
*m_object = object; *m_object = object;
@ -31,84 +31,84 @@ TextureGenerator::~TextureGenerator()
delete m_snapshot; delete m_snapshot;
} }
QImage *TextureGenerator::takeResultTextureColorImage() QImage* TextureGenerator::takeResultTextureColorImage()
{ {
QImage *resultTextureColorImage = m_resultTextureColorImage; QImage* resultTextureColorImage = m_resultTextureColorImage;
m_resultTextureColorImage = nullptr; m_resultTextureColorImage = nullptr;
return resultTextureColorImage; return resultTextureColorImage;
} }
QImage *TextureGenerator::takeResultTextureNormalImage() QImage* TextureGenerator::takeResultTextureNormalImage()
{ {
QImage *resultTextureNormalImage = m_resultTextureNormalImage; QImage* resultTextureNormalImage = m_resultTextureNormalImage;
m_resultTextureNormalImage = nullptr; m_resultTextureNormalImage = nullptr;
return resultTextureNormalImage; return resultTextureNormalImage;
} }
QImage *TextureGenerator::takeResultTextureRoughnessImage() QImage* TextureGenerator::takeResultTextureRoughnessImage()
{ {
QImage *resultTextureRoughnessImage = m_resultTextureRoughnessImage; QImage* resultTextureRoughnessImage = m_resultTextureRoughnessImage;
m_resultTextureRoughnessImage = nullptr; m_resultTextureRoughnessImage = nullptr;
return resultTextureRoughnessImage; return resultTextureRoughnessImage;
} }
QImage *TextureGenerator::takeResultTextureMetalnessImage() QImage* TextureGenerator::takeResultTextureMetalnessImage()
{ {
QImage *resultTextureMetalnessImage = m_resultTextureMetalnessImage; QImage* resultTextureMetalnessImage = m_resultTextureMetalnessImage;
m_resultTextureMetalnessImage = nullptr; m_resultTextureMetalnessImage = nullptr;
return resultTextureMetalnessImage; return resultTextureMetalnessImage;
} }
QImage *TextureGenerator::takeResultTextureAmbientOcclusionImage() QImage* TextureGenerator::takeResultTextureAmbientOcclusionImage()
{ {
QImage *resultTextureAmbientOcclusionImage = m_resultTextureAmbientOcclusionImage; QImage* resultTextureAmbientOcclusionImage = m_resultTextureAmbientOcclusionImage;
m_resultTextureAmbientOcclusionImage = nullptr; m_resultTextureAmbientOcclusionImage = nullptr;
return resultTextureAmbientOcclusionImage; return resultTextureAmbientOcclusionImage;
} }
dust3d::Object *TextureGenerator::takeObject() dust3d::Object* TextureGenerator::takeObject()
{ {
dust3d::Object *object = m_object; dust3d::Object* object = m_object;
m_object = nullptr; m_object = nullptr;
return object; return object;
} }
ModelMesh *TextureGenerator::takeResultMesh() ModelMesh* TextureGenerator::takeResultMesh()
{ {
ModelMesh *resultMesh = m_resultMesh; ModelMesh* resultMesh = m_resultMesh;
m_resultMesh = nullptr; m_resultMesh = nullptr;
return resultMesh; return resultMesh;
} }
void TextureGenerator::addPartColorMap(dust3d::Uuid partId, const QImage *image, float tileScale) void TextureGenerator::addPartColorMap(dust3d::Uuid partId, const QImage* image, float tileScale)
{ {
if (nullptr == image) if (nullptr == image)
return; return;
m_partColorTextureMap[partId] = std::make_pair(*image, tileScale); m_partColorTextureMap[partId] = std::make_pair(*image, tileScale);
} }
void TextureGenerator::addPartNormalMap(dust3d::Uuid partId, const QImage *image, float tileScale) void TextureGenerator::addPartNormalMap(dust3d::Uuid partId, const QImage* image, float tileScale)
{ {
if (nullptr == image) if (nullptr == image)
return; return;
m_partNormalTextureMap[partId] = std::make_pair(*image, tileScale); m_partNormalTextureMap[partId] = std::make_pair(*image, tileScale);
} }
void TextureGenerator::addPartMetalnessMap(dust3d::Uuid partId, const QImage *image, float tileScale) void TextureGenerator::addPartMetalnessMap(dust3d::Uuid partId, const QImage* image, float tileScale)
{ {
if (nullptr == image) if (nullptr == image)
return; return;
m_partMetalnessTextureMap[partId] = std::make_pair(*image, tileScale); m_partMetalnessTextureMap[partId] = std::make_pair(*image, tileScale);
} }
void TextureGenerator::addPartRoughnessMap(dust3d::Uuid partId, const QImage *image, float tileScale) void TextureGenerator::addPartRoughnessMap(dust3d::Uuid partId, const QImage* image, float tileScale)
{ {
if (nullptr == image) if (nullptr == image)
return; return;
m_partRoughnessTextureMap[partId] = std::make_pair(*image, tileScale); m_partRoughnessTextureMap[partId] = std::make_pair(*image, tileScale);
} }
void TextureGenerator::addPartAmbientOcclusionMap(dust3d::Uuid partId, const QImage *image, float tileScale) void TextureGenerator::addPartAmbientOcclusionMap(dust3d::Uuid partId, const QImage* image, float tileScale)
{ {
if (nullptr == image) if (nullptr == image)
return; return;
@ -119,28 +119,28 @@ void TextureGenerator::prepare()
{ {
if (nullptr == m_snapshot) if (nullptr == m_snapshot)
return; return;
std::map<dust3d::Uuid, dust3d::Uuid> updatedMaterialIdMap; std::map<dust3d::Uuid, dust3d::Uuid> updatedMaterialIdMap;
std::map<dust3d::Uuid, bool> updatedCountershadedMap; std::map<dust3d::Uuid, bool> updatedCountershadedMap;
for (const auto &partIt: m_snapshot->parts) { for (const auto& partIt : m_snapshot->parts) {
dust3d::Uuid materialId; dust3d::Uuid materialId;
auto materialIdIt = partIt.second.find("materialId"); auto materialIdIt = partIt.second.find("materialId");
if (materialIdIt != partIt.second.end()) if (materialIdIt != partIt.second.end())
materialId = dust3d::Uuid(materialIdIt->second); materialId = dust3d::Uuid(materialIdIt->second);
dust3d::Uuid partId = dust3d::Uuid(partIt.first); dust3d::Uuid partId = dust3d::Uuid(partIt.first);
updatedMaterialIdMap.insert({partId, materialId}); updatedMaterialIdMap.insert({ partId, materialId });
updatedCountershadedMap.insert({partId, updatedCountershadedMap.insert({ partId,
dust3d::String::isTrue(dust3d::String::valueOrEmpty(partIt.second, "countershaded"))}); dust3d::String::isTrue(dust3d::String::valueOrEmpty(partIt.second, "countershaded")) });
} }
for (const auto &bmeshNode: m_object->nodes) { for (const auto& bmeshNode : m_object->nodes) {
bool countershaded = bmeshNode.countershaded; bool countershaded = bmeshNode.countershaded;
auto findUpdatedCountershadedMap = updatedCountershadedMap.find(bmeshNode.mirrorFromPartId.isNull() ? bmeshNode.partId : bmeshNode.mirrorFromPartId); auto findUpdatedCountershadedMap = updatedCountershadedMap.find(bmeshNode.mirrorFromPartId.isNull() ? bmeshNode.partId : bmeshNode.mirrorFromPartId);
if (findUpdatedCountershadedMap != updatedCountershadedMap.end()) if (findUpdatedCountershadedMap != updatedCountershadedMap.end())
countershaded = findUpdatedCountershadedMap->second; countershaded = findUpdatedCountershadedMap->second;
if (countershaded) if (countershaded)
m_countershadedPartIds.insert(bmeshNode.partId); m_countershadedPartIds.insert(bmeshNode.partId);
for (size_t i = 0; i < (int)dust3d::TextureType::Count - 1; ++i) { for (size_t i = 0; i < (int)dust3d::TextureType::Count - 1; ++i) {
dust3d::TextureType forWhat = (dust3d::TextureType)(i + 1); dust3d::TextureType forWhat = (dust3d::TextureType)(i + 1);
MaterialTextures materialTextures; MaterialTextures materialTextures;
@ -150,7 +150,7 @@ void TextureGenerator::prepare()
materialId = findUpdatedMaterialIdResult->second; materialId = findUpdatedMaterialIdResult->second;
float tileScale = 1.0; float tileScale = 1.0;
initializeMaterialTexturesFromSnapshot(*m_snapshot, materialId, materialTextures, tileScale); initializeMaterialTexturesFromSnapshot(*m_snapshot, materialId, materialTextures, tileScale);
const QImage *image = materialTextures.textureImages[i]; const QImage* image = materialTextures.textureImages[i];
if (nullptr != image) { if (nullptr != image) {
if (dust3d::TextureType::BaseColor == forWhat) if (dust3d::TextureType::BaseColor == forWhat)
addPartColorMap(bmeshNode.partId, image, tileScale); addPartColorMap(bmeshNode.partId, image, tileScale);
@ -175,100 +175,100 @@ bool TextureGenerator::hasTransparencySettings()
void TextureGenerator::generate() void TextureGenerator::generate()
{ {
m_resultMesh = new ModelMesh(*m_object); m_resultMesh = new ModelMesh(*m_object);
if (nullptr == m_object->triangleVertexUvs()) if (nullptr == m_object->triangleVertexUvs())
return; return;
if (nullptr == m_object->triangleSourceNodes()) if (nullptr == m_object->triangleSourceNodes())
return; return;
if (nullptr == m_object->partUvRects()) if (nullptr == m_object->partUvRects())
return; return;
QElapsedTimer countTimeConsumed; QElapsedTimer countTimeConsumed;
countTimeConsumed.start(); countTimeConsumed.start();
prepare(); prepare();
bool hasNormalMap = false; bool hasNormalMap = false;
bool hasMetalnessMap = false; bool hasMetalnessMap = false;
bool hasRoughnessMap = false; bool hasRoughnessMap = false;
bool hasAmbientOcclusionMap = false; bool hasAmbientOcclusionMap = false;
const auto &triangleVertexUvs = *m_object->triangleVertexUvs(); const auto& triangleVertexUvs = *m_object->triangleVertexUvs();
const auto &triangleSourceNodes = *m_object->triangleSourceNodes(); const auto& triangleSourceNodes = *m_object->triangleSourceNodes();
const auto &partUvRects = *m_object->partUvRects(); const auto& partUvRects = *m_object->partUvRects();
const auto &triangleNormals = m_object->triangleNormals; const auto& triangleNormals = m_object->triangleNormals;
std::map<dust3d::Uuid, QColor> partColorMap; std::map<dust3d::Uuid, QColor> partColorMap;
std::map<std::pair<dust3d::Uuid, dust3d::Uuid>, const dust3d::ObjectNode *> nodeMap; std::map<std::pair<dust3d::Uuid, dust3d::Uuid>, const dust3d::ObjectNode*> nodeMap;
std::map<dust3d::Uuid, float> partColorSolubilityMap; std::map<dust3d::Uuid, float> partColorSolubilityMap;
std::map<dust3d::Uuid, float> partMetalnessMap; std::map<dust3d::Uuid, float> partMetalnessMap;
std::map<dust3d::Uuid, float> partRoughnessMap; std::map<dust3d::Uuid, float> partRoughnessMap;
for (const auto &item: m_object->nodes) { for (const auto& item : m_object->nodes) {
if (!m_hasTransparencySettings) { if (!m_hasTransparencySettings) {
if (!qFuzzyCompare(1.0, item.color.alpha())) if (!qFuzzyCompare(1.0, item.color.alpha()))
m_hasTransparencySettings = true; m_hasTransparencySettings = true;
} }
nodeMap.insert({{item.partId, item.nodeId}, &item}); nodeMap.insert({ { item.partId, item.nodeId }, &item });
partColorMap.insert({item.partId, QColor(item.color.toString().c_str())}); partColorMap.insert({ item.partId, QColor(item.color.toString().c_str()) });
partColorSolubilityMap.insert({item.partId, item.colorSolubility}); partColorSolubilityMap.insert({ item.partId, item.colorSolubility });
partMetalnessMap.insert({item.partId, item.metalness}); partMetalnessMap.insert({ item.partId, item.metalness });
partRoughnessMap.insert({item.partId, item.roughness}); partRoughnessMap.insert({ item.partId, item.roughness });
} }
m_resultTextureColorImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32); m_resultTextureColorImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32);
m_resultTextureColorImage->fill(m_hasTransparencySettings ? m_defaultTextureColor : Qt::white); m_resultTextureColorImage->fill(m_hasTransparencySettings ? m_defaultTextureColor : Qt::white);
m_resultTextureNormalImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32); m_resultTextureNormalImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32);
m_resultTextureNormalImage->fill(QColor(128, 128, 255)); m_resultTextureNormalImage->fill(QColor(128, 128, 255));
m_resultTextureMetalnessImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32); m_resultTextureMetalnessImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32);
m_resultTextureMetalnessImage->fill(Qt::black); m_resultTextureMetalnessImage->fill(Qt::black);
m_resultTextureRoughnessImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32); m_resultTextureRoughnessImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32);
m_resultTextureRoughnessImage->fill(Qt::white); m_resultTextureRoughnessImage->fill(Qt::white);
m_resultTextureAmbientOcclusionImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32); m_resultTextureAmbientOcclusionImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32);
m_resultTextureAmbientOcclusionImage->fill(Qt::white); m_resultTextureAmbientOcclusionImage->fill(Qt::white);
QColor borderColor = Qt::darkGray; QColor borderColor = Qt::darkGray;
QPen pen(borderColor); QPen pen(borderColor);
QPainter texturePainter; QPainter texturePainter;
texturePainter.begin(m_resultTextureColorImage); texturePainter.begin(m_resultTextureColorImage);
texturePainter.setRenderHint(QPainter::Antialiasing); texturePainter.setRenderHint(QPainter::Antialiasing);
texturePainter.setRenderHint(QPainter::HighQualityAntialiasing); texturePainter.setRenderHint(QPainter::HighQualityAntialiasing);
QPainter textureNormalPainter; QPainter textureNormalPainter;
textureNormalPainter.begin(m_resultTextureNormalImage); textureNormalPainter.begin(m_resultTextureNormalImage);
textureNormalPainter.setRenderHint(QPainter::Antialiasing); textureNormalPainter.setRenderHint(QPainter::Antialiasing);
textureNormalPainter.setRenderHint(QPainter::HighQualityAntialiasing); textureNormalPainter.setRenderHint(QPainter::HighQualityAntialiasing);
QPainter textureMetalnessPainter; QPainter textureMetalnessPainter;
textureMetalnessPainter.begin(m_resultTextureMetalnessImage); textureMetalnessPainter.begin(m_resultTextureMetalnessImage);
textureMetalnessPainter.setRenderHint(QPainter::Antialiasing); textureMetalnessPainter.setRenderHint(QPainter::Antialiasing);
textureMetalnessPainter.setRenderHint(QPainter::HighQualityAntialiasing); textureMetalnessPainter.setRenderHint(QPainter::HighQualityAntialiasing);
QPainter textureRoughnessPainter; QPainter textureRoughnessPainter;
textureRoughnessPainter.begin(m_resultTextureRoughnessImage); textureRoughnessPainter.begin(m_resultTextureRoughnessImage);
textureRoughnessPainter.setRenderHint(QPainter::Antialiasing); textureRoughnessPainter.setRenderHint(QPainter::Antialiasing);
textureRoughnessPainter.setRenderHint(QPainter::HighQualityAntialiasing); textureRoughnessPainter.setRenderHint(QPainter::HighQualityAntialiasing);
QPainter textureAmbientOcclusionPainter; QPainter textureAmbientOcclusionPainter;
textureAmbientOcclusionPainter.begin(m_resultTextureAmbientOcclusionImage); textureAmbientOcclusionPainter.begin(m_resultTextureAmbientOcclusionImage);
textureAmbientOcclusionPainter.setRenderHint(QPainter::Antialiasing); textureAmbientOcclusionPainter.setRenderHint(QPainter::Antialiasing);
textureAmbientOcclusionPainter.setRenderHint(QPainter::HighQualityAntialiasing); textureAmbientOcclusionPainter.setRenderHint(QPainter::HighQualityAntialiasing);
texturePainter.setPen(Qt::NoPen); texturePainter.setPen(Qt::NoPen);
for (const auto &it: partUvRects) { for (const auto& it : partUvRects) {
const auto &partId = it.first; const auto& partId = it.first;
const auto &rects = it.second; const auto& rects = it.second;
auto findSourceColorResult = partColorMap.find(partId); auto findSourceColorResult = partColorMap.find(partId);
if (findSourceColorResult != partColorMap.end()) { if (findSourceColorResult != partColorMap.end()) {
const auto &color = findSourceColorResult->second; const auto& color = findSourceColorResult->second;
QBrush brush(color); QBrush brush(color);
float fillExpandSize = 2; float fillExpandSize = 2;
for (const auto &rect: rects) { for (const auto& rect : rects) {
QRectF translatedRect = { QRectF translatedRect = {
rect.left() * TextureGenerator::m_textureSize - fillExpandSize, rect.left() * TextureGenerator::m_textureSize - fillExpandSize,
rect.top() * TextureGenerator::m_textureSize - fillExpandSize, rect.top() * TextureGenerator::m_textureSize - fillExpandSize,
@ -279,20 +279,20 @@ void TextureGenerator::generate()
} }
} }
} }
for (const auto &it: partUvRects) { for (const auto& it : partUvRects) {
const auto &partId = it.first; const auto& partId = it.first;
const auto &rects = it.second; const auto& rects = it.second;
auto findMetalnessResult = partMetalnessMap.find(partId); auto findMetalnessResult = partMetalnessMap.find(partId);
if (findMetalnessResult != partMetalnessMap.end()) { if (findMetalnessResult != partMetalnessMap.end()) {
if (qFuzzyCompare(findMetalnessResult->second, (float)0.0)) if (qFuzzyCompare(findMetalnessResult->second, (float)0.0))
continue; continue;
const auto &color = QColor(findMetalnessResult->second * 255, const auto& color = QColor(findMetalnessResult->second * 255,
findMetalnessResult->second * 255, findMetalnessResult->second * 255,
findMetalnessResult->second * 255); findMetalnessResult->second * 255);
QBrush brush(color); QBrush brush(color);
float fillExpandSize = 2; float fillExpandSize = 2;
for (const auto &rect: rects) { for (const auto& rect : rects) {
QRectF translatedRect = { QRectF translatedRect = {
rect.left() * TextureGenerator::m_textureSize - fillExpandSize, rect.left() * TextureGenerator::m_textureSize - fillExpandSize,
rect.top() * TextureGenerator::m_textureSize - fillExpandSize, rect.top() * TextureGenerator::m_textureSize - fillExpandSize,
@ -304,20 +304,20 @@ void TextureGenerator::generate()
} }
} }
} }
for (const auto &it: partUvRects) { for (const auto& it : partUvRects) {
const auto &partId = it.first; const auto& partId = it.first;
const auto &rects = it.second; const auto& rects = it.second;
auto findRoughnessResult = partRoughnessMap.find(partId); auto findRoughnessResult = partRoughnessMap.find(partId);
if (findRoughnessResult != partRoughnessMap.end()) { if (findRoughnessResult != partRoughnessMap.end()) {
if (qFuzzyCompare(findRoughnessResult->second, (float)1.0)) if (qFuzzyCompare(findRoughnessResult->second, (float)1.0))
continue; continue;
const auto &color = QColor(findRoughnessResult->second * 255, const auto& color = QColor(findRoughnessResult->second * 255,
findRoughnessResult->second * 255, findRoughnessResult->second * 255,
findRoughnessResult->second * 255); findRoughnessResult->second * 255);
QBrush brush(color); QBrush brush(color);
float fillExpandSize = 2; float fillExpandSize = 2;
for (const auto &rect: rects) { for (const auto& rect : rects) {
QRectF translatedRect = { QRectF translatedRect = {
rect.left() * TextureGenerator::m_textureSize - fillExpandSize, rect.left() * TextureGenerator::m_textureSize - fillExpandSize,
rect.top() * TextureGenerator::m_textureSize - fillExpandSize, rect.top() * TextureGenerator::m_textureSize - fillExpandSize,
@ -329,25 +329,25 @@ void TextureGenerator::generate()
} }
} }
} }
auto drawTexture = [&](const std::map<dust3d::Uuid, std::pair<QPixmap, QPixmap>> &map, QPainter &painter, bool useAlpha) { auto drawTexture = [&](const std::map<dust3d::Uuid, std::pair<QPixmap, QPixmap>>& map, QPainter& painter, bool useAlpha) {
for (const auto &it: partUvRects) { for (const auto& it : partUvRects) {
const auto &partId = it.first; const auto& partId = it.first;
const auto &rects = it.second; const auto& rects = it.second;
float alpha = 1.0; float alpha = 1.0;
if (useAlpha) { if (useAlpha) {
auto findSourceColorResult = partColorMap.find(partId); auto findSourceColorResult = partColorMap.find(partId);
if (findSourceColorResult != partColorMap.end()) { if (findSourceColorResult != partColorMap.end()) {
const auto &color = findSourceColorResult->second; const auto& color = findSourceColorResult->second;
alpha = color.alphaF(); alpha = color.alphaF();
} }
} }
auto findTextureResult = map.find(partId); auto findTextureResult = map.find(partId);
if (findTextureResult != map.end()) { if (findTextureResult != map.end()) {
const auto &pixmap = findTextureResult->second.first; const auto& pixmap = findTextureResult->second.first;
const auto &rotatedPixmap = findTextureResult->second.second; const auto& rotatedPixmap = findTextureResult->second.second;
painter.setOpacity(alpha); painter.setOpacity(alpha);
for (const auto &rect: rects) { for (const auto& rect : rects) {
QRectF translatedRect = { QRectF translatedRect = {
rect.left() * TextureGenerator::m_textureSize, rect.left() * TextureGenerator::m_textureSize,
rect.top() * TextureGenerator::m_textureSize, rect.top() * TextureGenerator::m_textureSize,
@ -364,12 +364,12 @@ void TextureGenerator::generate()
} }
} }
}; };
auto convertTextureImageToPixmap = [&](const std::map<dust3d::Uuid, std::pair<QImage, float>> &sourceMap, auto convertTextureImageToPixmap = [&](const std::map<dust3d::Uuid, std::pair<QImage, float>>& sourceMap,
std::map<dust3d::Uuid, std::pair<QPixmap, QPixmap>> &targetMap) { std::map<dust3d::Uuid, std::pair<QPixmap, QPixmap>>& targetMap) {
for (const auto &it: sourceMap) { for (const auto& it : sourceMap) {
float tileScale = it.second.second; float tileScale = it.second.second;
const auto &image = it.second.first; const auto& image = it.second.first;
auto newSize = image.size() * tileScale; auto newSize = image.size() * tileScale;
QImage scaledImage = image.scaled(newSize); QImage scaledImage = image.scaled(newSize);
QPoint center = scaledImage.rect().center(); QPoint center = scaledImage.rect().center();
@ -381,53 +381,52 @@ void TextureGenerator::generate()
QPixmap::fromImage(rotatedImage)); QPixmap::fromImage(rotatedImage));
} }
}; };
std::map<dust3d::Uuid, std::pair<QPixmap, QPixmap>> partColorTexturePixmaps; std::map<dust3d::Uuid, std::pair<QPixmap, QPixmap>> partColorTexturePixmaps;
std::map<dust3d::Uuid, std::pair<QPixmap, QPixmap>> partNormalTexturePixmaps; std::map<dust3d::Uuid, std::pair<QPixmap, QPixmap>> partNormalTexturePixmaps;
std::map<dust3d::Uuid, std::pair<QPixmap, QPixmap>> partMetalnessTexturePixmaps; std::map<dust3d::Uuid, std::pair<QPixmap, QPixmap>> partMetalnessTexturePixmaps;
std::map<dust3d::Uuid, std::pair<QPixmap, QPixmap>> partRoughnessTexturePixmaps; std::map<dust3d::Uuid, std::pair<QPixmap, QPixmap>> partRoughnessTexturePixmaps;
std::map<dust3d::Uuid, std::pair<QPixmap, QPixmap>> partAmbientOcclusionTexturePixmaps; std::map<dust3d::Uuid, std::pair<QPixmap, QPixmap>> partAmbientOcclusionTexturePixmaps;
convertTextureImageToPixmap(m_partColorTextureMap, partColorTexturePixmaps); convertTextureImageToPixmap(m_partColorTextureMap, partColorTexturePixmaps);
convertTextureImageToPixmap(m_partNormalTextureMap, partNormalTexturePixmaps); convertTextureImageToPixmap(m_partNormalTextureMap, partNormalTexturePixmaps);
convertTextureImageToPixmap(m_partMetalnessTextureMap, partMetalnessTexturePixmaps); convertTextureImageToPixmap(m_partMetalnessTextureMap, partMetalnessTexturePixmaps);
convertTextureImageToPixmap(m_partRoughnessTextureMap, partRoughnessTexturePixmaps); convertTextureImageToPixmap(m_partRoughnessTextureMap, partRoughnessTexturePixmaps);
convertTextureImageToPixmap(m_partAmbientOcclusionTextureMap, partAmbientOcclusionTexturePixmaps); convertTextureImageToPixmap(m_partAmbientOcclusionTextureMap, partAmbientOcclusionTexturePixmaps);
drawTexture(partColorTexturePixmaps, texturePainter, true); drawTexture(partColorTexturePixmaps, texturePainter, true);
drawTexture(partNormalTexturePixmaps, textureNormalPainter, false); drawTexture(partNormalTexturePixmaps, textureNormalPainter, false);
drawTexture(partMetalnessTexturePixmaps, textureMetalnessPainter, false); drawTexture(partMetalnessTexturePixmaps, textureMetalnessPainter, false);
drawTexture(partRoughnessTexturePixmaps, textureRoughnessPainter, false); drawTexture(partRoughnessTexturePixmaps, textureRoughnessPainter, false);
drawTexture(partAmbientOcclusionTexturePixmaps, textureAmbientOcclusionPainter, false); drawTexture(partAmbientOcclusionTexturePixmaps, textureAmbientOcclusionPainter, false);
auto drawBySolubility = [&](const dust3d::Uuid &partId, size_t triangleIndex, size_t firstVertexIndex, size_t secondVertexIndex, auto drawBySolubility = [&](const dust3d::Uuid& partId, size_t triangleIndex, size_t firstVertexIndex, size_t secondVertexIndex,
const dust3d::Uuid &neighborPartId) { const dust3d::Uuid& neighborPartId) {
const std::vector<dust3d::Vector2> &uv = triangleVertexUvs[triangleIndex]; const std::vector<dust3d::Vector2>& uv = triangleVertexUvs[triangleIndex];
const auto &allRects = partUvRects.find(partId); const auto& allRects = partUvRects.find(partId);
if (allRects == partUvRects.end()) { if (allRects == partUvRects.end()) {
qDebug() << "Found part uv rects failed"; qDebug() << "Found part uv rects failed";
return; return;
} }
const auto &firstPoint = uv[firstVertexIndex]; const auto& firstPoint = uv[firstVertexIndex];
const auto &secondPoint = uv[secondVertexIndex]; const auto& secondPoint = uv[secondVertexIndex];
auto edgeLength = (firstPoint - secondPoint).length(); auto edgeLength = (firstPoint - secondPoint).length();
auto middlePoint = (firstPoint + secondPoint) / 2.0; auto middlePoint = (firstPoint + secondPoint) / 2.0;
float alpha = 1.0; float alpha = 1.0;
const auto &findColor = partColorMap.find(partId); const auto& findColor = partColorMap.find(partId);
if (findColor == partColorMap.end()) if (findColor == partColorMap.end())
return; return;
alpha = findColor->second.alphaF(); alpha = findColor->second.alphaF();
const auto &findNeighborColorSolubility = partColorSolubilityMap.find(neighborPartId); const auto& findNeighborColorSolubility = partColorSolubilityMap.find(neighborPartId);
if (findNeighborColorSolubility == partColorSolubilityMap.end()) if (findNeighborColorSolubility == partColorSolubilityMap.end())
return; return;
if (qFuzzyIsNull(findNeighborColorSolubility->second)) if (qFuzzyIsNull(findNeighborColorSolubility->second))
return; return;
const auto &findNeighborColor = partColorMap.find(neighborPartId); const auto& findNeighborColor = partColorMap.find(neighborPartId);
if (findNeighborColor == partColorMap.end()) if (findNeighborColor == partColorMap.end())
return; return;
for (const auto &it: allRects->second) { for (const auto& it : allRects->second) {
if (it.contains(firstPoint.x(), firstPoint.y()) || if (it.contains(firstPoint.x(), firstPoint.y()) || it.contains(secondPoint.x(), secondPoint.y())) {
it.contains(secondPoint.x(), secondPoint.y())) {
float finalRadius = (it.width() + it.height()) * 0.5 * findNeighborColorSolubility->second; float finalRadius = (it.width() + it.height()) * 0.5 * findNeighborColorSolubility->second;
if (finalRadius < edgeLength) if (finalRadius < edgeLength)
finalRadius = edgeLength; finalRadius = edgeLength;
@ -445,14 +444,14 @@ void TextureGenerator::generate()
texturePainter.setOpacity(alpha); texturePainter.setOpacity(alpha);
auto findTextureResult = partColorTexturePixmaps.find(neighborPartId); auto findTextureResult = partColorTexturePixmaps.find(neighborPartId);
if (findTextureResult != partColorTexturePixmaps.end()) { if (findTextureResult != partColorTexturePixmaps.end()) {
const auto &pixmap = findTextureResult->second.first; const auto& pixmap = findTextureResult->second.first;
const auto &rotatedPixmap = findTextureResult->second.second; const auto& rotatedPixmap = findTextureResult->second.second;
QImage tmpImage(translatedRect.width(), translatedRect.height(), QImage::Format_ARGB32); QImage tmpImage(translatedRect.width(), translatedRect.height(), QImage::Format_ARGB32);
QPixmap tmpPixmap = QPixmap::fromImage(tmpImage); QPixmap tmpPixmap = QPixmap::fromImage(tmpImage);
QPainter tmpPainter; QPainter tmpPainter;
QRectF tmpImageFrame = QRectF(0, 0, translatedRect.width(), translatedRect.height()); QRectF tmpImageFrame = QRectF(0, 0, translatedRect.width(), translatedRect.height());
// Fill tiled texture // Fill tiled texture
tmpPainter.begin(&tmpPixmap); tmpPainter.begin(&tmpPixmap);
tmpPainter.setOpacity(alpha); tmpPainter.setOpacity(alpha);
@ -463,23 +462,23 @@ void TextureGenerator::generate()
} }
tmpPainter.setOpacity(1.0); tmpPainter.setOpacity(1.0);
tmpPainter.end(); tmpPainter.end();
// Apply gradient // Apply gradient
QRadialGradient gradient(QPointF(middlePoint.x() * TextureGenerator::m_textureSize - translatedRect.left(), QRadialGradient gradient(QPointF(middlePoint.x() * TextureGenerator::m_textureSize - translatedRect.left(),
middlePoint.y() * TextureGenerator::m_textureSize - translatedRect.top()), middlePoint.y() * TextureGenerator::m_textureSize - translatedRect.top()),
finalRadius * TextureGenerator::m_textureSize); finalRadius * TextureGenerator::m_textureSize);
gradient.setColorAt(0.0, findNeighborColor->second); gradient.setColorAt(0.0, findNeighborColor->second);
gradient.setColorAt(1.0, Qt::transparent); gradient.setColorAt(1.0, Qt::transparent);
tmpPainter.begin(&tmpPixmap); tmpPainter.begin(&tmpPixmap);
tmpPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn); tmpPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
tmpPainter.fillRect(tmpImageFrame, gradient); tmpPainter.fillRect(tmpImageFrame, gradient);
tmpPainter.end(); tmpPainter.end();
texturePainter.drawPixmap(translatedRect, tmpPixmap, tmpImageFrame); texturePainter.drawPixmap(translatedRect, tmpPixmap, tmpImageFrame);
} else { } else {
QRadialGradient gradient(QPointF(middlePoint.x() * TextureGenerator::m_textureSize, QRadialGradient gradient(QPointF(middlePoint.x() * TextureGenerator::m_textureSize,
middlePoint.y() * TextureGenerator::m_textureSize), middlePoint.y() * TextureGenerator::m_textureSize),
finalRadius * TextureGenerator::m_textureSize); finalRadius * TextureGenerator::m_textureSize);
gradient.setColorAt(0.0, findNeighborColor->second); gradient.setColorAt(0.0, findNeighborColor->second);
gradient.setColorAt(1.0, Qt::transparent); gradient.setColorAt(1.0, Qt::transparent);
@ -490,10 +489,10 @@ void TextureGenerator::generate()
} }
} }
}; };
std::map<std::pair<size_t, size_t>, std::tuple<size_t, size_t, size_t>> halfEdgeToTriangleMap; std::map<std::pair<size_t, size_t>, std::tuple<size_t, size_t, size_t>> halfEdgeToTriangleMap;
for (size_t i = 0; i < m_object->triangles.size(); ++i) { for (size_t i = 0; i < m_object->triangles.size(); ++i) {
const auto &triangleIndices = m_object->triangles[i]; const auto& triangleIndices = m_object->triangles[i];
if (triangleIndices.size() != 3) { if (triangleIndices.size() != 3) {
qDebug() << "Found invalid triangle indices"; qDebug() << "Found invalid triangle indices";
continue; continue;
@ -504,38 +503,38 @@ void TextureGenerator::generate()
std::make_tuple(i, j, k))); std::make_tuple(i, j, k)));
} }
} }
for (const auto &it: halfEdgeToTriangleMap) { for (const auto& it : halfEdgeToTriangleMap) {
auto oppositeHalfEdge = std::make_pair(it.first.second, it.first.first); auto oppositeHalfEdge = std::make_pair(it.first.second, it.first.first);
const auto &opposite = halfEdgeToTriangleMap.find(oppositeHalfEdge); const auto& opposite = halfEdgeToTriangleMap.find(oppositeHalfEdge);
if (opposite == halfEdgeToTriangleMap.end()) if (opposite == halfEdgeToTriangleMap.end())
continue; continue;
const std::pair<dust3d::Uuid, dust3d::Uuid> &source = triangleSourceNodes[std::get<0>(it.second)]; const std::pair<dust3d::Uuid, dust3d::Uuid>& source = triangleSourceNodes[std::get<0>(it.second)];
const std::pair<dust3d::Uuid, dust3d::Uuid> &oppositeSource = triangleSourceNodes[std::get<0>(opposite->second)]; const std::pair<dust3d::Uuid, dust3d::Uuid>& oppositeSource = triangleSourceNodes[std::get<0>(opposite->second)];
if (source.first == oppositeSource.first) if (source.first == oppositeSource.first)
continue; continue;
drawBySolubility(source.first, std::get<0>(it.second), std::get<1>(it.second), std::get<2>(it.second), oppositeSource.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); drawBySolubility(oppositeSource.first, std::get<0>(opposite->second), std::get<1>(opposite->second), std::get<2>(opposite->second), source.first);
} }
// Draw belly white // Draw belly white
texturePainter.setCompositionMode(QPainter::CompositionMode_SoftLight); texturePainter.setCompositionMode(QPainter::CompositionMode_SoftLight);
for (size_t triangleIndex = 0; triangleIndex < m_object->triangles.size(); ++triangleIndex) { for (size_t triangleIndex = 0; triangleIndex < m_object->triangles.size(); ++triangleIndex) {
const auto &normal = triangleNormals[triangleIndex]; const auto& normal = triangleNormals[triangleIndex];
const std::pair<dust3d::Uuid, dust3d::Uuid> &source = triangleSourceNodes[triangleIndex]; const std::pair<dust3d::Uuid, dust3d::Uuid>& source = triangleSourceNodes[triangleIndex];
const auto &partId = source.first; const auto& partId = source.first;
if (m_countershadedPartIds.find(partId) == m_countershadedPartIds.end()) if (m_countershadedPartIds.find(partId) == m_countershadedPartIds.end())
continue; continue;
const auto &allRects = partUvRects.find(partId); const auto& allRects = partUvRects.find(partId);
if (allRects == partUvRects.end()) { if (allRects == partUvRects.end()) {
qDebug() << "Found part uv rects failed"; qDebug() << "Found part uv rects failed";
continue; continue;
} }
const auto &findObjectNode = nodeMap.find(source); const auto& findObjectNode = nodeMap.find(source);
if (findObjectNode == nodeMap.end()) if (findObjectNode == nodeMap.end())
continue; continue;
const dust3d::ObjectNode *objectNode = findObjectNode->second; const dust3d::ObjectNode* objectNode = findObjectNode->second;
if (qAbs(dust3d::Vector3::dotProduct(objectNode->direction, dust3d::Vector3(0, 1, 0))) >= 0.707) { if (qAbs(dust3d::Vector3::dotProduct(objectNode->direction, dust3d::Vector3(0, 1, 0))) >= 0.707) {
if (dust3d::Vector3::dotProduct(normal, dust3d::Vector3(0, 0, 1)) <= 0.0) if (dust3d::Vector3::dotProduct(normal, dust3d::Vector3(0, 0, 1)) <= 0.0)
continue; continue;
@ -543,24 +542,22 @@ void TextureGenerator::generate()
if (dust3d::Vector3::dotProduct(normal, dust3d::Vector3(0, -1, 0)) <= 0.0) if (dust3d::Vector3::dotProduct(normal, dust3d::Vector3(0, -1, 0)) <= 0.0)
continue; continue;
} }
const auto &triangleIndices = m_object->triangles[triangleIndex]; const auto& triangleIndices = m_object->triangles[triangleIndex];
if (triangleIndices.size() != 3) { if (triangleIndices.size() != 3) {
qDebug() << "Found invalid triangle indices"; qDebug() << "Found invalid triangle indices";
continue; continue;
} }
const std::vector<dust3d::Vector2> &uv = triangleVertexUvs[triangleIndex]; const std::vector<dust3d::Vector2>& uv = triangleVertexUvs[triangleIndex];
dust3d::Vector2 middlePoint = (uv[0] + uv[1] + uv[2]) / 3.0; dust3d::Vector2 middlePoint = (uv[0] + uv[1] + uv[2]) / 3.0;
float finalRadius = ((uv[0] - uv[1]).length() + float finalRadius = ((uv[0] - uv[1]).length() + (uv[1] - uv[2]).length() + (uv[2] - uv[0]).length()) / 3.0;
(uv[1] - uv[2]).length() +
(uv[2] - uv[0]).length()) / 3.0;
QRadialGradient gradient(QPointF(middlePoint.x() * TextureGenerator::m_textureSize, QRadialGradient gradient(QPointF(middlePoint.x() * TextureGenerator::m_textureSize,
middlePoint.y() * TextureGenerator::m_textureSize), middlePoint.y() * TextureGenerator::m_textureSize),
finalRadius * TextureGenerator::m_textureSize); finalRadius * TextureGenerator::m_textureSize);
gradient.setColorAt(0.0, Qt::white); gradient.setColorAt(0.0, Qt::white);
gradient.setColorAt(1.0, Qt::transparent); gradient.setColorAt(1.0, Qt::transparent);
for (const auto &it: allRects->second) { for (const auto& it : allRects->second) {
if (it.contains(middlePoint.x(), middlePoint.y())) { if (it.contains(middlePoint.x(), middlePoint.y())) {
dust3d::Rectangle fillTarget((middlePoint.x() - finalRadius), dust3d::Rectangle fillTarget((middlePoint.x() - finalRadius),
(middlePoint.y() - finalRadius), (middlePoint.y() - finalRadius),
@ -576,31 +573,31 @@ void TextureGenerator::generate()
texturePainter.fillRect(translatedRect, gradient); texturePainter.fillRect(translatedRect, gradient);
} }
} }
// Fill the neighbor halfedges // Fill the neighbor halfedges
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
int j = (i + 1) % 3; int j = (i + 1) % 3;
auto oppositeHalfEdge = std::make_pair(triangleIndices[j], triangleIndices[i]); auto oppositeHalfEdge = std::make_pair(triangleIndices[j], triangleIndices[i]);
const auto &opposite = halfEdgeToTriangleMap.find(oppositeHalfEdge); const auto& opposite = halfEdgeToTriangleMap.find(oppositeHalfEdge);
if (opposite == halfEdgeToTriangleMap.end()) if (opposite == halfEdgeToTriangleMap.end())
continue; continue;
auto oppositeTriangleIndex = std::get<0>(opposite->second); auto oppositeTriangleIndex = std::get<0>(opposite->second);
const std::pair<dust3d::Uuid, dust3d::Uuid> &oppositeSource = triangleSourceNodes[oppositeTriangleIndex]; const std::pair<dust3d::Uuid, dust3d::Uuid>& oppositeSource = triangleSourceNodes[oppositeTriangleIndex];
if (partId == oppositeSource.first) if (partId == oppositeSource.first)
continue; continue;
const auto &oppositeAllRects = partUvRects.find(oppositeSource.first); const auto& oppositeAllRects = partUvRects.find(oppositeSource.first);
if (oppositeAllRects == partUvRects.end()) { if (oppositeAllRects == partUvRects.end()) {
qDebug() << "Found part uv rects failed"; qDebug() << "Found part uv rects failed";
continue; continue;
} }
const std::vector<dust3d::Vector2> &oppositeUv = triangleVertexUvs[oppositeTriangleIndex]; const std::vector<dust3d::Vector2>& oppositeUv = triangleVertexUvs[oppositeTriangleIndex];
dust3d::Vector2 oppositeMiddlePoint = (oppositeUv[std::get<1>(opposite->second)] + oppositeUv[std::get<2>(opposite->second)]) * 0.5; dust3d::Vector2 oppositeMiddlePoint = (oppositeUv[std::get<1>(opposite->second)] + oppositeUv[std::get<2>(opposite->second)]) * 0.5;
QRadialGradient oppositeGradient(QPointF(oppositeMiddlePoint.x() * TextureGenerator::m_textureSize, QRadialGradient oppositeGradient(QPointF(oppositeMiddlePoint.x() * TextureGenerator::m_textureSize,
oppositeMiddlePoint.y() * TextureGenerator::m_textureSize), oppositeMiddlePoint.y() * TextureGenerator::m_textureSize),
finalRadius * TextureGenerator::m_textureSize); finalRadius * TextureGenerator::m_textureSize);
oppositeGradient.setColorAt(0.0, Qt::white); oppositeGradient.setColorAt(0.0, Qt::white);
oppositeGradient.setColorAt(1.0, Qt::transparent); oppositeGradient.setColorAt(1.0, Qt::transparent);
for (const auto &it: oppositeAllRects->second) { for (const auto& it : oppositeAllRects->second) {
if (it.contains(oppositeMiddlePoint.x(), oppositeMiddlePoint.y())) { if (it.contains(oppositeMiddlePoint.x(), oppositeMiddlePoint.y())) {
dust3d::Rectangle fillTarget((oppositeMiddlePoint.x() - finalRadius), dust3d::Rectangle fillTarget((oppositeMiddlePoint.x() - finalRadius),
(oppositeMiddlePoint.y() - finalRadius), (oppositeMiddlePoint.y() - finalRadius),
@ -618,7 +615,7 @@ void TextureGenerator::generate()
} }
} }
} }
hasNormalMap = !m_partNormalTextureMap.empty(); hasNormalMap = !m_partNormalTextureMap.empty();
if (!m_partMetalnessTextureMap.empty()) if (!m_partMetalnessTextureMap.empty())
hasMetalnessMap = true; hasMetalnessMap = true;
@ -631,12 +628,12 @@ void TextureGenerator::generate()
textureMetalnessPainter.end(); textureMetalnessPainter.end();
textureRoughnessPainter.end(); textureRoughnessPainter.end();
textureAmbientOcclusionPainter.end(); textureAmbientOcclusionPainter.end();
if (!hasNormalMap) { if (!hasNormalMap) {
delete m_resultTextureNormalImage; delete m_resultTextureNormalImage;
m_resultTextureNormalImage = nullptr; m_resultTextureNormalImage = nullptr;
} }
if (!hasMetalnessMap && !hasRoughnessMap && !hasAmbientOcclusionMap) { if (!hasMetalnessMap && !hasRoughnessMap && !hasAmbientOcclusionMap) {
delete m_resultTextureMetalnessImage; delete m_resultTextureMetalnessImage;
m_resultTextureMetalnessImage = nullptr; m_resultTextureMetalnessImage = nullptr;
@ -647,7 +644,7 @@ void TextureGenerator::generate()
delete m_resultTextureAmbientOcclusionImage; delete m_resultTextureAmbientOcclusionImage;
m_resultTextureAmbientOcclusionImage = nullptr; m_resultTextureAmbientOcclusionImage = nullptr;
} }
m_resultMesh->setTextureImage(new QImage(*m_resultTextureColorImage)); m_resultMesh->setTextureImage(new QImage(*m_resultTextureColorImage));
if (nullptr != m_resultTextureNormalImage) if (nullptr != m_resultTextureNormalImage)
m_resultMesh->setNormalMapImage(new QImage(*m_resultTextureNormalImage)); m_resultMesh->setNormalMapImage(new QImage(*m_resultTextureNormalImage));
@ -660,18 +657,16 @@ void TextureGenerator::generate()
m_resultMesh->setHasRoughnessInImage(hasRoughnessMap); m_resultMesh->setHasRoughnessInImage(hasRoughnessMap);
m_resultMesh->setHasAmbientOcclusionInImage(hasAmbientOcclusionMap); m_resultMesh->setHasAmbientOcclusionInImage(hasAmbientOcclusionMap);
} }
qDebug() << "The texture[" << TextureGenerator::m_textureSize << "x" << TextureGenerator::m_textureSize << "] generation took" << countTimeConsumed.elapsed() << "milliseconds"; qDebug() << "The texture[" << TextureGenerator::m_textureSize << "x" << TextureGenerator::m_textureSize << "] generation took" << countTimeConsumed.elapsed() << "milliseconds";
} }
QImage *TextureGenerator::combineMetalnessRoughnessAmbientOcclusionImages(QImage *metalnessImage, QImage* TextureGenerator::combineMetalnessRoughnessAmbientOcclusionImages(QImage* metalnessImage,
QImage *roughnessImage, QImage* roughnessImage,
QImage *ambientOcclusionImage) QImage* ambientOcclusionImage)
{ {
QImage *textureMetalnessRoughnessAmbientOcclusionImage = nullptr; QImage* textureMetalnessRoughnessAmbientOcclusionImage = nullptr;
if (nullptr != metalnessImage || if (nullptr != metalnessImage || nullptr != roughnessImage || nullptr != ambientOcclusionImage) {
nullptr != roughnessImage ||
nullptr != ambientOcclusionImage) {
int textureSize = 0; int textureSize = 0;
if (nullptr != metalnessImage) if (nullptr != metalnessImage)
textureSize = metalnessImage->height(); textureSize = metalnessImage->height();

View File

@ -1,61 +1,63 @@
#ifndef DUST3D_APPLICATION_TEXTURE_GENERATOR_H_ #ifndef DUST3D_APPLICATION_TEXTURE_GENERATOR_H_
#define DUST3D_APPLICATION_TEXTURE_GENERATOR_H_ #define DUST3D_APPLICATION_TEXTURE_GENERATOR_H_
#include <QObject> #include "model_mesh.h"
#include <vector>
#include <QImage>
#include <QColor> #include <QColor>
#include <QImage>
#include <QObject>
#include <QPixmap> #include <QPixmap>
#include <dust3d/base/object.h> #include <dust3d/base/object.h>
#include <dust3d/base/snapshot.h> #include <dust3d/base/snapshot.h>
#include "model_mesh.h" #include <vector>
class TextureGenerator : public QObject class TextureGenerator : public QObject {
{
Q_OBJECT Q_OBJECT
public: public:
TextureGenerator(const dust3d::Object &object, dust3d::Snapshot *snapshot=nullptr); TextureGenerator(const dust3d::Object& object, dust3d::Snapshot* snapshot = nullptr);
~TextureGenerator(); ~TextureGenerator();
QImage *takeResultTextureColorImage(); QImage* takeResultTextureColorImage();
QImage *takeResultTextureNormalImage(); QImage* takeResultTextureNormalImage();
QImage *takeResultTextureRoughnessImage(); QImage* takeResultTextureRoughnessImage();
QImage *takeResultTextureMetalnessImage(); QImage* takeResultTextureMetalnessImage();
QImage *takeResultTextureAmbientOcclusionImage(); QImage* takeResultTextureAmbientOcclusionImage();
dust3d::Object *takeObject(); dust3d::Object* takeObject();
ModelMesh *takeResultMesh(); ModelMesh* takeResultMesh();
bool hasTransparencySettings(); bool hasTransparencySettings();
void addPartColorMap(dust3d::Uuid partId, const QImage *image, float tileScale); void addPartColorMap(dust3d::Uuid partId, const QImage* image, float tileScale);
void addPartNormalMap(dust3d::Uuid partId, const QImage *image, float tileScale); void addPartNormalMap(dust3d::Uuid partId, const QImage* image, float tileScale);
void addPartMetalnessMap(dust3d::Uuid partId, const QImage *image, float tileScale); void addPartMetalnessMap(dust3d::Uuid partId, const QImage* image, float tileScale);
void addPartRoughnessMap(dust3d::Uuid partId, const QImage *image, float tileScale); void addPartRoughnessMap(dust3d::Uuid partId, const QImage* image, float tileScale);
void addPartAmbientOcclusionMap(dust3d::Uuid partId, const QImage *image, float tileScale); void addPartAmbientOcclusionMap(dust3d::Uuid partId, const QImage* image, float tileScale);
void generate(); void generate();
static QImage *combineMetalnessRoughnessAmbientOcclusionImages(QImage *metalnessImage, static QImage* combineMetalnessRoughnessAmbientOcclusionImages(QImage* metalnessImage,
QImage *roughnessImage, QImage* roughnessImage,
QImage *ambientOcclusionImage); QImage* ambientOcclusionImage);
signals: signals:
void finished(); void finished();
public slots: public slots:
void process(); void process();
public: public:
static QColor m_defaultTextureColor; static QColor m_defaultTextureColor;
private: private:
void prepare(); void prepare();
private: private:
dust3d::Object *m_object = nullptr; dust3d::Object* m_object = nullptr;
QImage *m_resultTextureColorImage = nullptr; QImage* m_resultTextureColorImage = nullptr;
QImage *m_resultTextureNormalImage = nullptr; QImage* m_resultTextureNormalImage = nullptr;
QImage *m_resultTextureRoughnessImage = nullptr; QImage* m_resultTextureRoughnessImage = nullptr;
QImage *m_resultTextureMetalnessImage = nullptr; QImage* m_resultTextureMetalnessImage = nullptr;
QImage *m_resultTextureAmbientOcclusionImage = nullptr; QImage* m_resultTextureAmbientOcclusionImage = nullptr;
ModelMesh *m_resultMesh = nullptr; ModelMesh* m_resultMesh = nullptr;
std::map<dust3d::Uuid, std::pair<QImage, float>> m_partColorTextureMap; std::map<dust3d::Uuid, std::pair<QImage, float>> m_partColorTextureMap;
std::map<dust3d::Uuid, std::pair<QImage, float>> m_partNormalTextureMap; std::map<dust3d::Uuid, std::pair<QImage, float>> m_partNormalTextureMap;
std::map<dust3d::Uuid, std::pair<QImage, float>> m_partMetalnessTextureMap; std::map<dust3d::Uuid, std::pair<QImage, float>> m_partMetalnessTextureMap;
std::map<dust3d::Uuid, std::pair<QImage, float>> m_partRoughnessTextureMap; std::map<dust3d::Uuid, std::pair<QImage, float>> m_partRoughnessTextureMap;
std::map<dust3d::Uuid, std::pair<QImage, float>> m_partAmbientOcclusionTextureMap; std::map<dust3d::Uuid, std::pair<QImage, float>> m_partAmbientOcclusionTextureMap;
std::set<dust3d::Uuid> m_countershadedPartIds; std::set<dust3d::Uuid> m_countershadedPartIds;
dust3d::Snapshot *m_snapshot = nullptr; dust3d::Snapshot* m_snapshot = nullptr;
bool m_hasTransparencySettings = false; bool m_hasTransparencySettings = false;
int m_textureSize = 1024; int m_textureSize = 1024;
}; };

Some files were not shown because too many files have changed in this diff Show More