Apply webkit style clang format on code base
parent
73f0404c2e
commit
57b1a802f3
|
@ -1,18 +1,18 @@
|
||||||
|
#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);
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
class AboutWidget : public QDialog
|
class AboutWidget : public QDialog {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
AboutWidget();
|
AboutWidget();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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,31 +82,30 @@ 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;
|
||||||
|
@ -119,13 +118,12 @@ QVariant ComponentListModel::data(const QModelIndex &index, int role) const
|
||||||
}
|
}
|
||||||
return component->previewPixmap;
|
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;
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -1,41 +1,41 @@
|
||||||
#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);
|
||||||
|
@ -45,7 +45,7 @@ ComponentPropertyWidget::ComponentPropertyWidget(Document *document,
|
||||||
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);
|
||||||
|
@ -55,7 +55,7 @@ ComponentPropertyWidget::ComponentPropertyWidget(Document *document,
|
||||||
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, [=]() {
|
||||||
|
@ -63,7 +63,7 @@ ComponentPropertyWidget::ComponentPropertyWidget(Document *document,
|
||||||
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, [=]() {
|
||||||
|
@ -71,16 +71,16 @@ ComponentPropertyWidget::ComponentPropertyWidget(Document *document,
|
||||||
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);
|
||||||
|
@ -90,7 +90,7 @@ ComponentPropertyWidget::ComponentPropertyWidget(Document *document,
|
||||||
emit groupOperationAdded();
|
emit groupOperationAdded();
|
||||||
});
|
});
|
||||||
|
|
||||||
QHBoxLayout *deformUnifyLayout = new QHBoxLayout;
|
QHBoxLayout* deformUnifyLayout = new QHBoxLayout;
|
||||||
deformUnifyLayout->addStretch();
|
deformUnifyLayout->addStretch();
|
||||||
deformUnifyLayout->addWidget(deformUnifyStateBox);
|
deformUnifyLayout->addWidget(deformUnifyStateBox);
|
||||||
|
|
||||||
|
@ -102,9 +102,9 @@ 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);
|
||||||
|
@ -114,7 +114,7 @@ ComponentPropertyWidget::ComponentPropertyWidget(Document *document,
|
||||||
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, [=]() {
|
||||||
|
@ -122,7 +122,7 @@ ComponentPropertyWidget::ComponentPropertyWidget(Document *document,
|
||||||
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, [=]() {
|
||||||
|
@ -130,7 +130,7 @@ ComponentPropertyWidget::ComponentPropertyWidget(Document *document,
|
||||||
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, [=]() {
|
||||||
|
@ -138,13 +138,13 @@ ComponentPropertyWidget::ComponentPropertyWidget(Document *document,
|
||||||
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);
|
||||||
|
@ -154,7 +154,7 @@ ComponentPropertyWidget::ComponentPropertyWidget(Document *document,
|
||||||
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);
|
||||||
|
@ -164,7 +164,7 @@ ComponentPropertyWidget::ComponentPropertyWidget(Document *document,
|
||||||
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);
|
||||||
|
@ -174,13 +174,13 @@ ComponentPropertyWidget::ComponentPropertyWidget(Document *document,
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -235,15 +235,15 @@ 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;
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
#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())
|
||||||
|
@ -30,7 +30,7 @@ QImage *buildCutFaceTemplatePreviewImage(const std::vector<dust3d::Vector2> &cut
|
||||||
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));
|
||||||
}
|
}
|
||||||
|
@ -45,13 +45,13 @@ QImage *buildCutFaceTemplatePreviewImage(const std::vector<dust3d::Vector2> &cut
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -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",
|
||||||
|
@ -366,8 +366,8 @@ typedef struct {
|
||||||
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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,7 +381,7 @@ std::unique_ptr<std::vector<std::unique_ptr<QOpenGLTexture>>> DdsFileReader::cre
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
@ -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,7 +504,7 @@ 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);
|
||||||
|
|
||||||
|
@ -514,7 +514,7 @@ QOpenGLTexture *DdsFileReader::createOpenGLTexture()
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,7 +148,7 @@ 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;
|
||||||
|
@ -158,7 +157,7 @@ void Document::updateTextureImage(QImage *image)
|
||||||
textureImage = image;
|
textureImage = image;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Document::updateTextureNormalImage(QImage *image)
|
void Document::updateTextureNormalImage(QImage* image)
|
||||||
{
|
{
|
||||||
delete textureNormalImageByteArray;
|
delete textureNormalImageByteArray;
|
||||||
textureNormalImageByteArray = nullptr;
|
textureNormalImageByteArray = nullptr;
|
||||||
|
@ -167,7 +166,7 @@ void Document::updateTextureNormalImage(QImage *image)
|
||||||
textureNormalImage = image;
|
textureNormalImage = image;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Document::updateTextureMetalnessImage(QImage *image)
|
void Document::updateTextureMetalnessImage(QImage* image)
|
||||||
{
|
{
|
||||||
delete textureMetalnessImageByteArray;
|
delete textureMetalnessImageByteArray;
|
||||||
textureMetalnessImageByteArray = nullptr;
|
textureMetalnessImageByteArray = nullptr;
|
||||||
|
@ -176,7 +175,7 @@ void Document::updateTextureMetalnessImage(QImage *image)
|
||||||
textureMetalnessImage = image;
|
textureMetalnessImage = image;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Document::updateTextureRoughnessImage(QImage *image)
|
void Document::updateTextureRoughnessImage(QImage* image)
|
||||||
{
|
{
|
||||||
delete textureRoughnessImageByteArray;
|
delete textureRoughnessImageByteArray;
|
||||||
textureRoughnessImageByteArray = nullptr;
|
textureRoughnessImageByteArray = nullptr;
|
||||||
|
@ -185,7 +184,7 @@ void Document::updateTextureRoughnessImage(QImage *image)
|
||||||
textureRoughnessImage = image;
|
textureRoughnessImage = image;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Document::updateTextureAmbientOcclusionImage(QImage *image)
|
void Document::updateTextureAmbientOcclusionImage(QImage* image)
|
||||||
{
|
{
|
||||||
delete textureAmbientOcclusionImageByteArray;
|
delete textureAmbientOcclusionImageByteArray;
|
||||||
textureAmbientOcclusionImageByteArray = nullptr;
|
textureAmbientOcclusionImageByteArray = nullptr;
|
||||||
|
@ -203,23 +202,22 @@ void Document::setEditMode(SkeletonDocumentEditMode 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,17 +395,14 @@ 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));
|
||||||
|
@ -426,8 +418,8 @@ void Document::addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSo
|
||||||
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)];
|
||||||
|
@ -670,13 +656,13 @@ void Document::addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -685,15 +671,15 @@ void Document::addFromSnapshot(const dust3d::Snapshot &snapshot, enum SnapshotSo
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,26 +735,26 @@ 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();
|
||||||
|
@ -852,9 +838,9 @@ void Document::generateMesh()
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -886,10 +872,10 @@ void Document::generateTexture()
|
||||||
|
|
||||||
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);
|
||||||
|
@ -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,14 +1444,10 @@ 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;
|
||||||
|
@ -1487,7 +1468,7 @@ void Document::addMaterial(dust3d::Uuid materialId, QString name, std::vector<Ma
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -1647,13 +1628,13 @@ void Document::collectCutFaceList(std::vector<QString> &cutFaces) const
|
||||||
|
|
||||||
// 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,7 +1644,7 @@ 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];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1673,6 +1654,6 @@ void Document::collectCutFaceList(std::vector<QString> &cutFaces) const
|
||||||
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()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,20 +118,22 @@ 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();
|
||||||
|
@ -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 ¤tPostProcessedObject() 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;
|
||||||
|
|
|
@ -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,9 +45,9 @@ 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;
|
||||||
|
|
||||||
|
@ -65,8 +65,8 @@ bool DocumentSaver::save(const QString *filename,
|
||||||
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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -1,80 +1,81 @@
|
||||||
#include <QVBoxLayout>
|
#include "document_window.h"
|
||||||
#include <QHBoxLayout>
|
#include "about_widget.h"
|
||||||
#include <QLabel>
|
#include "cut_face_preview.h"
|
||||||
#include <QGridLayout>
|
#include "document.h"
|
||||||
#include <QToolBar>
|
#include "document_saver.h"
|
||||||
#include <QPushButton>
|
#include "fbx_file.h"
|
||||||
#include <QFileDialog>
|
#include "float_number_widget.h"
|
||||||
#include <QTabWidget>
|
#include "flow_layout.h"
|
||||||
#include <QtCore/qbuffer.h>
|
#include "glb_file.h"
|
||||||
#include <QMessageBox>
|
#include "horizontal_line_widget.h"
|
||||||
#include <QTimer>
|
#include "image_forever.h"
|
||||||
#include <QMenuBar>
|
#include "log_browser.h"
|
||||||
#include <QPointer>
|
#include "material_manage_widget.h"
|
||||||
|
#include "part_manage_widget.h"
|
||||||
|
#include "preferences.h"
|
||||||
|
#include "skeleton_graphics_widget.h"
|
||||||
|
#include "spinnable_toolbar_icon.h"
|
||||||
|
#include "texture_generator.h"
|
||||||
|
#include "theme.h"
|
||||||
|
#include "updates_check_widget.h"
|
||||||
|
#include "version.h"
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <map>
|
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
#include <QDockWidget>
|
|
||||||
#include <QWidgetAction>
|
|
||||||
#include <QGraphicsOpacityEffect>
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QDockWidget>
|
||||||
|
#include <QFileDialog>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QFormLayout>
|
#include <QFormLayout>
|
||||||
#include <QTextBrowser>
|
#include <QGraphicsOpacityEffect>
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QMenuBar>
|
||||||
|
#include <QMessageBox>
|
||||||
#include <QMimeData>
|
#include <QMimeData>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
|
#include <QPointer>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QTabWidget>
|
||||||
|
#include <QTextBrowser>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QToolBar>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QWidgetAction>
|
||||||
|
#include <QtCore/qbuffer.h>
|
||||||
|
#include <dust3d/base/debug.h>
|
||||||
#include <dust3d/base/ds3_file.h>
|
#include <dust3d/base/ds3_file.h>
|
||||||
#include <dust3d/base/snapshot.h>
|
#include <dust3d/base/snapshot.h>
|
||||||
#include <dust3d/base/snapshot_xml.h>
|
#include <dust3d/base/snapshot_xml.h>
|
||||||
#include <dust3d/base/debug.h>
|
#include <map>
|
||||||
#include "document_window.h"
|
|
||||||
#include "skeleton_graphics_widget.h"
|
|
||||||
#include "theme.h"
|
|
||||||
#include "log_browser.h"
|
|
||||||
#include "about_widget.h"
|
|
||||||
#include "version.h"
|
|
||||||
#include "glb_file.h"
|
|
||||||
#include "part_manage_widget.h"
|
|
||||||
#include "material_manage_widget.h"
|
|
||||||
#include "image_forever.h"
|
|
||||||
#include "spinnable_toolbar_icon.h"
|
|
||||||
#include "fbx_file.h"
|
|
||||||
#include "float_number_widget.h"
|
|
||||||
#include "updates_check_widget.h"
|
|
||||||
#include "document_saver.h"
|
|
||||||
#include "document.h"
|
|
||||||
#include "preferences.h"
|
|
||||||
#include "flow_layout.h"
|
|
||||||
#include "cut_face_preview.h"
|
|
||||||
#include "horizontal_line_widget.h"
|
|
||||||
#include "texture_generator.h"
|
|
||||||
|
|
||||||
LogBrowser *g_logBrowser = nullptr;
|
LogBrowser* g_logBrowser = nullptr;
|
||||||
std::map<DocumentWindow *, dust3d::Uuid> g_documentWindows;
|
std::map<DocumentWindow*, dust3d::Uuid> g_documentWindows;
|
||||||
QTextBrowser *g_acknowlegementsWidget = nullptr;
|
QTextBrowser* g_acknowlegementsWidget = nullptr;
|
||||||
AboutWidget *g_aboutWidget = nullptr;
|
AboutWidget* g_aboutWidget = nullptr;
|
||||||
QTextBrowser *g_contributorsWidget = nullptr;
|
QTextBrowser* g_contributorsWidget = nullptr;
|
||||||
QTextBrowser *g_supportersWidget = nullptr;
|
QTextBrowser* g_supportersWidget = nullptr;
|
||||||
UpdatesCheckWidget *g_updatesCheckWidget = nullptr;
|
UpdatesCheckWidget* g_updatesCheckWidget = nullptr;
|
||||||
|
|
||||||
void outputMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
|
void outputMessage(QtMsgType type, const QMessageLogContext& context, const QString& msg)
|
||||||
{
|
{
|
||||||
if (g_logBrowser)
|
if (g_logBrowser)
|
||||||
g_logBrowser->outputMessage(type, msg, context.file, context.line);
|
g_logBrowser->outputMessage(type, msg, context.file, context.line);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ensureFileExtension(QString* filename, const QString extension) {
|
void ensureFileExtension(QString* filename, const QString extension)
|
||||||
|
{
|
||||||
if (!filename->endsWith(extension)) {
|
if (!filename->endsWith(extension)) {
|
||||||
filename->append(extension);
|
filename->append(extension);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<DocumentWindow *, dust3d::Uuid> &DocumentWindow::documentWindows()
|
const std::map<DocumentWindow*, dust3d::Uuid>& DocumentWindow::documentWindows()
|
||||||
{
|
{
|
||||||
return g_documentWindows;
|
return g_documentWindows;
|
||||||
}
|
}
|
||||||
|
|
||||||
Document *DocumentWindow::document()
|
Document* DocumentWindow::document()
|
||||||
{
|
{
|
||||||
return m_document;
|
return m_document;
|
||||||
}
|
}
|
||||||
|
@ -160,21 +161,21 @@ DocumentWindow::DocumentWindow()
|
||||||
qInstallMessageHandler(&outputMessage);
|
qInstallMessageHandler(&outputMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_documentWindows.insert({this, dust3d::Uuid::createUuid()});
|
g_documentWindows.insert({ this, dust3d::Uuid::createUuid() });
|
||||||
|
|
||||||
m_document = new Document;
|
m_document = new Document;
|
||||||
|
|
||||||
SkeletonGraphicsWidget *canvasGraphicsWidget = new SkeletonGraphicsWidget(m_document);
|
SkeletonGraphicsWidget* canvasGraphicsWidget = new SkeletonGraphicsWidget(m_document);
|
||||||
m_canvasGraphicsWidget = canvasGraphicsWidget;
|
m_canvasGraphicsWidget = canvasGraphicsWidget;
|
||||||
|
|
||||||
QVBoxLayout *toolButtonLayout = new QVBoxLayout;
|
QVBoxLayout* toolButtonLayout = new QVBoxLayout;
|
||||||
toolButtonLayout->setSpacing(0);
|
toolButtonLayout->setSpacing(0);
|
||||||
toolButtonLayout->setContentsMargins(5, 10, 4, 0);
|
toolButtonLayout->setContentsMargins(5, 10, 4, 0);
|
||||||
|
|
||||||
ToolbarButton *addButton = new ToolbarButton(":/resources/toolbar_add.svg");
|
ToolbarButton* addButton = new ToolbarButton(":/resources/toolbar_add.svg");
|
||||||
addButton->setToolTip(tr("Add node to canvas"));
|
addButton->setToolTip(tr("Add node to canvas"));
|
||||||
|
|
||||||
ToolbarButton *selectButton = new ToolbarButton(":/resources/toolbar_pointer.svg");
|
ToolbarButton* selectButton = new ToolbarButton(":/resources/toolbar_pointer.svg");
|
||||||
selectButton->setToolTip(tr("Select node on canvas"));
|
selectButton->setToolTip(tr("Select node on canvas"));
|
||||||
|
|
||||||
m_xLockButton = new ToolbarButton();
|
m_xLockButton = new ToolbarButton();
|
||||||
|
@ -219,17 +220,16 @@ DocumentWindow::DocumentWindow()
|
||||||
toolButtonLayout->addSpacing(20);
|
toolButtonLayout->addSpacing(20);
|
||||||
toolButtonLayout->addWidget(m_inprogressIndicator);
|
toolButtonLayout->addWidget(m_inprogressIndicator);
|
||||||
|
|
||||||
|
QLabel* verticalLogoLabel = new QLabel;
|
||||||
QLabel *verticalLogoLabel = new QLabel;
|
|
||||||
QImage verticalLogoImage;
|
QImage verticalLogoImage;
|
||||||
verticalLogoImage.load(":/resources/dust3d-vertical.png");
|
verticalLogoImage.load(":/resources/dust3d-vertical.png");
|
||||||
verticalLogoLabel->setPixmap(QPixmap::fromImage(verticalLogoImage));
|
verticalLogoLabel->setPixmap(QPixmap::fromImage(verticalLogoImage));
|
||||||
|
|
||||||
QHBoxLayout *logoLayout = new QHBoxLayout;
|
QHBoxLayout* logoLayout = new QHBoxLayout;
|
||||||
logoLayout->addWidget(verticalLogoLabel);
|
logoLayout->addWidget(verticalLogoLabel);
|
||||||
logoLayout->setContentsMargins(0, 0, 0, 0);
|
logoLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
QVBoxLayout *mainLeftLayout = new QVBoxLayout;
|
QVBoxLayout* mainLeftLayout = new QVBoxLayout;
|
||||||
mainLeftLayout->setSpacing(0);
|
mainLeftLayout->setSpacing(0);
|
||||||
mainLeftLayout->setContentsMargins(0, 0, 0, 0);
|
mainLeftLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
mainLeftLayout->addLayout(toolButtonLayout);
|
mainLeftLayout->addLayout(toolButtonLayout);
|
||||||
|
@ -237,9 +237,9 @@ DocumentWindow::DocumentWindow()
|
||||||
mainLeftLayout->addLayout(logoLayout);
|
mainLeftLayout->addLayout(logoLayout);
|
||||||
mainLeftLayout->addSpacing(10);
|
mainLeftLayout->addSpacing(10);
|
||||||
|
|
||||||
GraphicsContainerWidget *containerWidget = new GraphicsContainerWidget;
|
GraphicsContainerWidget* containerWidget = new GraphicsContainerWidget;
|
||||||
containerWidget->setGraphicsWidget(canvasGraphicsWidget);
|
containerWidget->setGraphicsWidget(canvasGraphicsWidget);
|
||||||
QGridLayout *containerLayout = new QGridLayout;
|
QGridLayout* containerLayout = new QGridLayout;
|
||||||
containerLayout->setSpacing(0);
|
containerLayout->setSpacing(0);
|
||||||
containerLayout->setContentsMargins(1, 0, 0, 0);
|
containerLayout->setContentsMargins(1, 0, 0, 0);
|
||||||
containerLayout->addWidget(canvasGraphicsWidget);
|
containerLayout->addWidget(canvasGraphicsWidget);
|
||||||
|
@ -265,22 +265,22 @@ DocumentWindow::DocumentWindow()
|
||||||
|
|
||||||
setTabPosition(Qt::RightDockWidgetArea, QTabWidget::East);
|
setTabPosition(Qt::RightDockWidgetArea, QTabWidget::East);
|
||||||
|
|
||||||
QDockWidget *partsDocker = new QDockWidget(tr("Parts"), this);
|
QDockWidget* partsDocker = new QDockWidget(tr("Parts"), this);
|
||||||
partsDocker->setAllowedAreas(Qt::RightDockWidgetArea);
|
partsDocker->setAllowedAreas(Qt::RightDockWidgetArea);
|
||||||
m_partManageWidget = new PartManageWidget(m_document);
|
m_partManageWidget = new PartManageWidget(m_document);
|
||||||
partsDocker->setWidget(m_partManageWidget);
|
partsDocker->setWidget(m_partManageWidget);
|
||||||
addDockWidget(Qt::RightDockWidgetArea, partsDocker);
|
addDockWidget(Qt::RightDockWidgetArea, partsDocker);
|
||||||
|
|
||||||
QDockWidget *materialDocker = new QDockWidget(tr("Materials"), this);
|
QDockWidget* materialDocker = new QDockWidget(tr("Materials"), this);
|
||||||
materialDocker->setAllowedAreas(Qt::RightDockWidgetArea);
|
materialDocker->setAllowedAreas(Qt::RightDockWidgetArea);
|
||||||
MaterialManageWidget *materialManageWidget = new MaterialManageWidget(m_document, materialDocker);
|
MaterialManageWidget* materialManageWidget = new MaterialManageWidget(m_document, materialDocker);
|
||||||
materialDocker->setWidget(materialManageWidget);
|
materialDocker->setWidget(materialManageWidget);
|
||||||
connect(materialManageWidget, &MaterialManageWidget::registerDialog, this, &DocumentWindow::registerDialog);
|
connect(materialManageWidget, &MaterialManageWidget::registerDialog, this, &DocumentWindow::registerDialog);
|
||||||
connect(materialManageWidget, &MaterialManageWidget::unregisterDialog, this, &DocumentWindow::unregisterDialog);
|
connect(materialManageWidget, &MaterialManageWidget::unregisterDialog, this, &DocumentWindow::unregisterDialog);
|
||||||
addDockWidget(Qt::RightDockWidgetArea, materialDocker);
|
addDockWidget(Qt::RightDockWidgetArea, materialDocker);
|
||||||
connect(materialDocker, &QDockWidget::topLevelChanged, [=](bool topLevel) {
|
connect(materialDocker, &QDockWidget::topLevelChanged, [=](bool topLevel) {
|
||||||
Q_UNUSED(topLevel);
|
Q_UNUSED(topLevel);
|
||||||
for (const auto &material: m_document->materialMap)
|
for (const auto& material : m_document->materialMap)
|
||||||
emit m_document->materialPreviewChanged(material.first);
|
emit m_document->materialPreviewChanged(material.first);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -288,28 +288,28 @@ DocumentWindow::DocumentWindow()
|
||||||
|
|
||||||
partsDocker->raise();
|
partsDocker->raise();
|
||||||
|
|
||||||
QWidget *titleBarWidget = new QWidget;
|
QWidget* titleBarWidget = new QWidget;
|
||||||
titleBarWidget->setFixedHeight(1);
|
titleBarWidget->setFixedHeight(1);
|
||||||
|
|
||||||
QHBoxLayout *titleBarLayout = new QHBoxLayout;
|
QHBoxLayout* titleBarLayout = new QHBoxLayout;
|
||||||
titleBarLayout->addStretch();
|
titleBarLayout->addStretch();
|
||||||
titleBarWidget->setLayout(titleBarLayout);
|
titleBarWidget->setLayout(titleBarLayout);
|
||||||
|
|
||||||
QVBoxLayout *canvasLayout = new QVBoxLayout;
|
QVBoxLayout* canvasLayout = new QVBoxLayout;
|
||||||
canvasLayout->setSpacing(0);
|
canvasLayout->setSpacing(0);
|
||||||
canvasLayout->setContentsMargins(0, 0, 0, 0);
|
canvasLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
canvasLayout->addWidget(titleBarWidget);
|
canvasLayout->addWidget(titleBarWidget);
|
||||||
canvasLayout->addWidget(containerWidget);
|
canvasLayout->addWidget(containerWidget);
|
||||||
canvasLayout->setStretch(1, 1);
|
canvasLayout->setStretch(1, 1);
|
||||||
|
|
||||||
QHBoxLayout *mainLayout = new QHBoxLayout;
|
QHBoxLayout* mainLayout = new QHBoxLayout;
|
||||||
mainLayout->setSpacing(0);
|
mainLayout->setSpacing(0);
|
||||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
mainLayout->addLayout(mainLeftLayout);
|
mainLayout->addLayout(mainLeftLayout);
|
||||||
mainLayout->addLayout(canvasLayout);
|
mainLayout->addLayout(canvasLayout);
|
||||||
mainLayout->addSpacing(3);
|
mainLayout->addSpacing(3);
|
||||||
|
|
||||||
QWidget *centralWidget = new QWidget;
|
QWidget* centralWidget = new QWidget;
|
||||||
centralWidget->setLayout(mainLayout);
|
centralWidget->setLayout(mainLayout);
|
||||||
|
|
||||||
setCentralWidget(centralWidget);
|
setCentralWidget(centralWidget);
|
||||||
|
@ -340,8 +340,8 @@ DocumentWindow::DocumentWindow()
|
||||||
"Screwdriver",
|
"Screwdriver",
|
||||||
"Seagull"
|
"Seagull"
|
||||||
};
|
};
|
||||||
for (const auto &model: exampleModels) {
|
for (const auto& model : exampleModels) {
|
||||||
QAction *openModelAction = new QAction(model, this);
|
QAction* openModelAction = new QAction(model, this);
|
||||||
connect(openModelAction, &QAction::triggered, this, [this, model]() {
|
connect(openModelAction, &QAction::triggered, this, [this, model]() {
|
||||||
openExample("model-" + model.toLower().replace(QChar(' '), QChar('-')) + ".ds3");
|
openExample("model-" + model.toLower().replace(QChar(' '), QChar('-')) + ".ds3");
|
||||||
});
|
});
|
||||||
|
@ -385,7 +385,7 @@ DocumentWindow::DocumentWindow()
|
||||||
m_fileMenu->addSeparator();
|
m_fileMenu->addSeparator();
|
||||||
|
|
||||||
for (int i = 0; i < Preferences::instance().maxRecentFiles(); ++i) {
|
for (int i = 0; i < Preferences::instance().maxRecentFiles(); ++i) {
|
||||||
QAction *action = new QAction(this);
|
QAction* action = new QAction(this);
|
||||||
action->setVisible(false);
|
action->setVisible(false);
|
||||||
connect(action, &QAction::triggered, this, &DocumentWindow::openRecentFile, Qt::QueuedConnection);
|
connect(action, &QAction::triggered, this, &DocumentWindow::openRecentFile, Qt::QueuedConnection);
|
||||||
m_recentFileActions.push_back(action);
|
m_recentFileActions.push_back(action);
|
||||||
|
@ -439,16 +439,16 @@ DocumentWindow::DocumentWindow()
|
||||||
});
|
});
|
||||||
m_windowMenu->addAction(m_showMaterialsAction);
|
m_windowMenu->addAction(m_showMaterialsAction);
|
||||||
|
|
||||||
QMenu *dialogsMenu = m_windowMenu->addMenu(tr("Dialogs"));
|
QMenu* dialogsMenu = m_windowMenu->addMenu(tr("Dialogs"));
|
||||||
connect(dialogsMenu, &QMenu::aboutToShow, [=]() {
|
connect(dialogsMenu, &QMenu::aboutToShow, [=]() {
|
||||||
dialogsMenu->clear();
|
dialogsMenu->clear();
|
||||||
if (this->m_dialogs.empty()) {
|
if (this->m_dialogs.empty()) {
|
||||||
QAction *action = dialogsMenu->addAction(tr("None"));
|
QAction* action = dialogsMenu->addAction(tr("None"));
|
||||||
action->setEnabled(false);
|
action->setEnabled(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (const auto &dialog: this->m_dialogs) {
|
for (const auto& dialog : this->m_dialogs) {
|
||||||
QAction *action = dialogsMenu->addAction(dialog->windowTitle());
|
QAction* action = dialogsMenu->addAction(dialog->windowTitle());
|
||||||
connect(action, &QAction::triggered, [=]() {
|
connect(action, &QAction::triggered, [=]() {
|
||||||
dialog->show();
|
dialog->show();
|
||||||
dialog->raise();
|
dialog->raise();
|
||||||
|
@ -659,7 +659,7 @@ DocumentWindow::DocumentWindow()
|
||||||
connect(m_document, &Document::turnaroundChanged, this, &DocumentWindow::documentChanged);
|
connect(m_document, &Document::turnaroundChanged, this, &DocumentWindow::documentChanged);
|
||||||
connect(m_document, &Document::optionsChanged, this, &DocumentWindow::documentChanged);
|
connect(m_document, &Document::optionsChanged, this, &DocumentWindow::documentChanged);
|
||||||
|
|
||||||
connect(m_modelRenderWidget, &ModelWidget::customContextMenuRequested, [=](const QPoint &pos) {
|
connect(m_modelRenderWidget, &ModelWidget::customContextMenuRequested, [=](const QPoint& pos) {
|
||||||
canvasGraphicsWidget->showContextMenu(canvasGraphicsWidget->mapFromGlobal(m_modelRenderWidget->mapToGlobal(pos)));
|
canvasGraphicsWidget->showContextMenu(canvasGraphicsWidget->mapFromGlobal(m_modelRenderWidget->mapToGlobal(pos)));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -681,10 +681,10 @@ DocumentWindow::DocumentWindow()
|
||||||
|
|
||||||
connect(this, &DocumentWindow::initialized, m_document, &Document::uiReady);
|
connect(this, &DocumentWindow::initialized, m_document, &Document::uiReady);
|
||||||
|
|
||||||
QTimer *timer = new QTimer(this);
|
QTimer* timer = new QTimer(this);
|
||||||
timer->setInterval(250);
|
timer->setInterval(250);
|
||||||
connect(timer, &QTimer::timeout, [=] {
|
connect(timer, &QTimer::timeout, [=] {
|
||||||
QWidget *focusedWidget = QApplication::focusWidget();
|
QWidget* focusedWidget = QApplication::focusWidget();
|
||||||
if (nullptr == focusedWidget && isActiveWindow())
|
if (nullptr == focusedWidget && isActiveWindow())
|
||||||
canvasGraphicsWidget->setFocus();
|
canvasGraphicsWidget->setFocus();
|
||||||
});
|
});
|
||||||
|
@ -693,11 +693,7 @@ DocumentWindow::DocumentWindow()
|
||||||
|
|
||||||
void DocumentWindow::updateInprogressIndicator()
|
void DocumentWindow::updateInprogressIndicator()
|
||||||
{
|
{
|
||||||
bool inprogress = m_document->isMeshGenerating() ||
|
bool inprogress = m_document->isMeshGenerating() || m_document->isPostProcessing() || m_document->isTextureGenerating() || nullptr != m_componentPreviewImagesGenerator || nullptr != m_componentPreviewImagesDecorator;
|
||||||
m_document->isPostProcessing() ||
|
|
||||||
m_document->isTextureGenerating() ||
|
|
||||||
nullptr != m_componentPreviewImagesGenerator ||
|
|
||||||
nullptr != m_componentPreviewImagesDecorator;
|
|
||||||
if (inprogress == m_inprogressIndicator->isSpinning())
|
if (inprogress == m_inprogressIndicator->isSpinning())
|
||||||
return;
|
return;
|
||||||
m_inprogressIndicator->showSpinner(inprogress);
|
m_inprogressIndicator->showSpinner(inprogress);
|
||||||
|
@ -711,9 +707,9 @@ void DocumentWindow::toggleRotation()
|
||||||
m_canvasGraphicsWidget->setRotated(!m_canvasGraphicsWidget->rotated());
|
m_canvasGraphicsWidget->setRotated(!m_canvasGraphicsWidget->rotated());
|
||||||
}
|
}
|
||||||
|
|
||||||
DocumentWindow *DocumentWindow::createDocumentWindow()
|
DocumentWindow* DocumentWindow::createDocumentWindow()
|
||||||
{
|
{
|
||||||
DocumentWindow *documentWindow = new DocumentWindow();
|
DocumentWindow* documentWindow = new DocumentWindow();
|
||||||
documentWindow->setAttribute(Qt::WA_DeleteOnClose);
|
documentWindow->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
|
||||||
QSize size = Preferences::instance().documentWindowSize();
|
QSize size = Preferences::instance().documentWindowSize();
|
||||||
|
@ -727,9 +723,9 @@ DocumentWindow *DocumentWindow::createDocumentWindow()
|
||||||
return documentWindow;
|
return documentWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentWindow::closeEvent(QCloseEvent *event)
|
void DocumentWindow::closeEvent(QCloseEvent* event)
|
||||||
{
|
{
|
||||||
if (! m_documentSaved) {
|
if (!m_documentSaved) {
|
||||||
QMessageBox::StandardButton answer = QMessageBox::question(this,
|
QMessageBox::StandardButton answer = QMessageBox::question(this,
|
||||||
APP_NAME,
|
APP_NAME,
|
||||||
tr("Do you really want to close while there are unsaved changes?"),
|
tr("Do you really want to close while there are unsaved changes?"),
|
||||||
|
@ -749,7 +745,7 @@ void DocumentWindow::closeEvent(QCloseEvent *event)
|
||||||
event->accept();
|
event->accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentWindow::setCurrentFilename(const QString &filename)
|
void DocumentWindow::setCurrentFilename(const QString& filename)
|
||||||
{
|
{
|
||||||
m_currentFilename = filename;
|
m_currentFilename = filename;
|
||||||
m_documentSaved = true;
|
m_documentSaved = true;
|
||||||
|
@ -806,7 +802,7 @@ void DocumentWindow::saveAs()
|
||||||
|
|
||||||
void DocumentWindow::saveAll()
|
void DocumentWindow::saveAll()
|
||||||
{
|
{
|
||||||
for (auto &it: g_documentWindows) {
|
for (auto& it : g_documentWindows) {
|
||||||
it.first->save();
|
it.first->save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -866,7 +862,7 @@ DocumentWindow::~DocumentWindow()
|
||||||
delete m_document;
|
delete m_document;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentWindow::showEvent(QShowEvent *event)
|
void DocumentWindow::showEvent(QShowEvent* event)
|
||||||
{
|
{
|
||||||
QMainWindow::showEvent(event);
|
QMainWindow::showEvent(event);
|
||||||
if (m_firstShow) {
|
if (m_firstShow) {
|
||||||
|
@ -878,7 +874,7 @@ void DocumentWindow::showEvent(QShowEvent *event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentWindow::mousePressEvent(QMouseEvent *event)
|
void DocumentWindow::mousePressEvent(QMouseEvent* event)
|
||||||
{
|
{
|
||||||
QMainWindow::mousePressEvent(event);
|
QMainWindow::mousePressEvent(event);
|
||||||
}
|
}
|
||||||
|
@ -886,7 +882,8 @@ void DocumentWindow::mousePressEvent(QMouseEvent *event)
|
||||||
void DocumentWindow::changeTurnaround()
|
void DocumentWindow::changeTurnaround()
|
||||||
{
|
{
|
||||||
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;
|
return;
|
||||||
QImage image;
|
QImage image;
|
||||||
|
@ -900,7 +897,7 @@ void DocumentWindow::save()
|
||||||
saveTo(m_currentFilename);
|
saveTo(m_currentFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentWindow::saveTo(const QString &saveAsFilename)
|
void DocumentWindow::saveTo(const QString& saveAsFilename)
|
||||||
{
|
{
|
||||||
QString filename = saveAsFilename;
|
QString filename = saveAsFilename;
|
||||||
|
|
||||||
|
@ -918,14 +915,13 @@ void DocumentWindow::saveTo(const QString &saveAsFilename)
|
||||||
m_document->toSnapshot(&snapshot);
|
m_document->toSnapshot(&snapshot);
|
||||||
if (DocumentSaver::save(&filename,
|
if (DocumentSaver::save(&filename,
|
||||||
&snapshot,
|
&snapshot,
|
||||||
(!m_document->turnaround.isNull() && m_document->turnaroundPngByteArray.size() > 0) ?
|
(!m_document->turnaround.isNull() && m_document->turnaroundPngByteArray.size() > 0) ? &m_document->turnaroundPngByteArray : nullptr)) {
|
||||||
&m_document->turnaroundPngByteArray : nullptr)) {
|
|
||||||
setCurrentFilename(filename);
|
setCurrentFilename(filename);
|
||||||
}
|
}
|
||||||
QApplication::restoreOverrideCursor();
|
QApplication::restoreOverrideCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentWindow::openPathAs(const QString &path, const QString &asName)
|
void DocumentWindow::openPathAs(const QString& path, const QString& asName)
|
||||||
{
|
{
|
||||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||||
|
|
||||||
|
@ -938,9 +934,9 @@ void DocumentWindow::openPathAs(const QString &path, const QString &asName)
|
||||||
file.open(QFile::ReadOnly);
|
file.open(QFile::ReadOnly);
|
||||||
QByteArray fileData = file.readAll();
|
QByteArray fileData = file.readAll();
|
||||||
|
|
||||||
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) {
|
||||||
const dust3d::Ds3ReaderItem &item = ds3Reader.items()[i];
|
const dust3d::Ds3ReaderItem& item = ds3Reader.items()[i];
|
||||||
qDebug() << "[" << i << "]item.name:" << item.name << "item.type:" << item.type;
|
qDebug() << "[" << i << "]item.name:" << item.name << "item.type:" << item.type;
|
||||||
if (item.type == "asset") {
|
if (item.type == "asset") {
|
||||||
if (dust3d::String::startsWith(item.name, "images/")) {
|
if (dust3d::String::startsWith(item.name, "images/")) {
|
||||||
|
@ -958,13 +954,13 @@ void DocumentWindow::openPathAs(const QString &path, const QString &asName)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < (int)ds3Reader.items().size(); ++i) {
|
for (int i = 0; i < (int)ds3Reader.items().size(); ++i) {
|
||||||
const dust3d::Ds3ReaderItem &item = ds3Reader.items()[i];
|
const dust3d::Ds3ReaderItem& item = ds3Reader.items()[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);
|
||||||
data.push_back('\0');
|
data.push_back('\0');
|
||||||
dust3d::Snapshot snapshot;
|
dust3d::Snapshot snapshot;
|
||||||
loadSnapshotFromXmlString(&snapshot, (char *)data.data());
|
loadSnapshotFromXmlString(&snapshot, (char*)data.data());
|
||||||
m_document->fromSnapshot(snapshot);
|
m_document->fromSnapshot(snapshot);
|
||||||
m_document->saveSnapshot();
|
m_document->saveSnapshot();
|
||||||
} else if (item.type == "asset") {
|
} else if (item.type == "asset") {
|
||||||
|
@ -980,14 +976,14 @@ void DocumentWindow::openPathAs(const QString &path, const QString &asName)
|
||||||
|
|
||||||
if (!asName.isEmpty()) {
|
if (!asName.isEmpty()) {
|
||||||
Preferences::instance().setCurrentFile(path);
|
Preferences::instance().setCurrentFile(path);
|
||||||
for (auto &it: g_documentWindows) {
|
for (auto& it : g_documentWindows) {
|
||||||
it.first->updateRecentFileActions();
|
it.first->updateRecentFileActions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setCurrentFilename(asName);
|
setCurrentFilename(asName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentWindow::openExample(const QString &modelName)
|
void DocumentWindow::openExample(const QString& modelName)
|
||||||
{
|
{
|
||||||
if (!m_documentSaved) {
|
if (!m_documentSaved) {
|
||||||
QMessageBox::StandardButton answer = QMessageBox::question(this,
|
QMessageBox::StandardButton answer = QMessageBox::question(this,
|
||||||
|
@ -1033,10 +1029,10 @@ void DocumentWindow::exportObjResult()
|
||||||
exportObjToFilename(filename);
|
exportObjToFilename(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentWindow::exportObjToFilename(const QString &filename)
|
void DocumentWindow::exportObjToFilename(const QString& filename)
|
||||||
{
|
{
|
||||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||||
ModelMesh *resultMesh = m_document->takeResultMesh();
|
ModelMesh* resultMesh = m_document->takeResultMesh();
|
||||||
if (nullptr != resultMesh) {
|
if (nullptr != resultMesh) {
|
||||||
resultMesh->exportAsObj(filename);
|
resultMesh->exportAsObj(filename);
|
||||||
delete resultMesh;
|
delete resultMesh;
|
||||||
|
@ -1055,7 +1051,7 @@ void DocumentWindow::exportFbxResult()
|
||||||
exportFbxToFilename(filename);
|
exportFbxToFilename(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentWindow::exportFbxToFilename(const QString &filename)
|
void DocumentWindow::exportFbxToFilename(const QString& filename)
|
||||||
{
|
{
|
||||||
if (!m_document->isExportReady()) {
|
if (!m_document->isExportReady()) {
|
||||||
qDebug() << "Export but document is not export ready";
|
qDebug() << "Export but document is not export ready";
|
||||||
|
@ -1085,7 +1081,7 @@ void DocumentWindow::exportGlbResult()
|
||||||
exportGlbToFilename(filename);
|
exportGlbToFilename(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentWindow::exportGlbToFilename(const QString &filename)
|
void DocumentWindow::exportGlbToFilename(const QString& filename)
|
||||||
{
|
{
|
||||||
if (!m_document->isExportReady()) {
|
if (!m_document->isExportReady()) {
|
||||||
qDebug() << "Export but document is not export ready";
|
qDebug() << "Export but document is not export ready";
|
||||||
|
@ -1093,8 +1089,7 @@ void DocumentWindow::exportGlbToFilename(const QString &filename)
|
||||||
}
|
}
|
||||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||||
dust3d::Object skeletonResult = m_document->currentPostProcessedObject();
|
dust3d::Object skeletonResult = m_document->currentPostProcessedObject();
|
||||||
QImage *textureMetalnessRoughnessAmbientOcclusionImage =
|
QImage* textureMetalnessRoughnessAmbientOcclusionImage = TextureGenerator::combineMetalnessRoughnessAmbientOcclusionImages(m_document->textureMetalnessImage,
|
||||||
TextureGenerator::combineMetalnessRoughnessAmbientOcclusionImages(m_document->textureMetalnessImage,
|
|
||||||
m_document->textureRoughnessImage,
|
m_document->textureRoughnessImage,
|
||||||
m_document->textureAmbientOcclusionImage);
|
m_document->textureAmbientOcclusionImage);
|
||||||
GlbFileWriter glbFileWriter(skeletonResult, filename,
|
GlbFileWriter glbFileWriter(skeletonResult, filename,
|
||||||
|
@ -1136,17 +1131,17 @@ void DocumentWindow::updateRadiusLockButtonState()
|
||||||
m_radiusLockButton->setIcon(":/resources/toolbar_radius.svg");
|
m_radiusLockButton->setIcon(":/resources/toolbar_radius.svg");
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentWindow::registerDialog(QWidget *widget)
|
void DocumentWindow::registerDialog(QWidget* widget)
|
||||||
{
|
{
|
||||||
m_dialogs.push_back(widget);
|
m_dialogs.push_back(widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentWindow::unregisterDialog(QWidget *widget)
|
void DocumentWindow::unregisterDialog(QWidget* widget)
|
||||||
{
|
{
|
||||||
m_dialogs.erase(std::remove(m_dialogs.begin(), m_dialogs.end(), widget), m_dialogs.end());
|
m_dialogs.erase(std::remove(m_dialogs.begin(), m_dialogs.end(), widget), m_dialogs.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentWindow::setExportWaitingList(const QStringList &filenames)
|
void DocumentWindow::setExportWaitingList(const QStringList& filenames)
|
||||||
{
|
{
|
||||||
m_waitingForExportToFilenames = filenames;
|
m_waitingForExportToFilenames = filenames;
|
||||||
}
|
}
|
||||||
|
@ -1160,7 +1155,7 @@ void DocumentWindow::checkExportWaitingList()
|
||||||
m_waitingForExportToFilenames.clear();
|
m_waitingForExportToFilenames.clear();
|
||||||
|
|
||||||
bool isSuccessful = m_document->isMeshGenerationSucceed();
|
bool isSuccessful = m_document->isMeshGenerationSucceed();
|
||||||
for (const auto &filename: list) {
|
for (const auto& filename : list) {
|
||||||
if (filename.endsWith(".obj")) {
|
if (filename.endsWith(".obj")) {
|
||||||
exportObjToFilename(filename);
|
exportObjToFilename(filename);
|
||||||
emit waitingExportFinished(filename, isSuccessful);
|
emit waitingExportFinished(filename, isSuccessful);
|
||||||
|
@ -1185,10 +1180,10 @@ void DocumentWindow::generateComponentPreviewImages()
|
||||||
|
|
||||||
m_isComponentPreviewImagesObsolete = false;
|
m_isComponentPreviewImagesObsolete = false;
|
||||||
|
|
||||||
QThread *thread = new QThread;
|
QThread* thread = new QThread;
|
||||||
|
|
||||||
m_componentPreviewImagesGenerator = new MeshPreviewImagesGenerator(new ModelOffscreenRender(m_modelRenderWidget->format()));
|
m_componentPreviewImagesGenerator = new MeshPreviewImagesGenerator(new ModelOffscreenRender(m_modelRenderWidget->format()));
|
||||||
for (auto &component: m_document->componentMap) {
|
for (auto& component : m_document->componentMap) {
|
||||||
if (!component.second.isPreviewMeshObsolete)
|
if (!component.second.isPreviewMeshObsolete)
|
||||||
continue;
|
continue;
|
||||||
component.second.isPreviewMeshObsolete = false;
|
component.second.isPreviewMeshObsolete = false;
|
||||||
|
@ -1209,7 +1204,7 @@ void DocumentWindow::componentPreviewImagesReady()
|
||||||
std::unique_ptr<std::map<dust3d::Uuid, QImage>> componentImages;
|
std::unique_ptr<std::map<dust3d::Uuid, QImage>> componentImages;
|
||||||
componentImages.reset(m_componentPreviewImagesGenerator->takeImages());
|
componentImages.reset(m_componentPreviewImagesGenerator->takeImages());
|
||||||
if (nullptr != componentImages) {
|
if (nullptr != componentImages) {
|
||||||
for (const auto &it: *componentImages) {
|
for (const auto& it : *componentImages) {
|
||||||
m_document->setComponentPreviewImage(it.first, std::make_unique<QImage>(std::move(it.second)));
|
m_document->setComponentPreviewImage(it.first, std::make_unique<QImage>(std::move(it.second)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1234,10 +1229,10 @@ void DocumentWindow::decorateComponentPreviewImages()
|
||||||
|
|
||||||
m_isComponentPreviewImageDecorationsObsolete = false;
|
m_isComponentPreviewImageDecorationsObsolete = false;
|
||||||
|
|
||||||
QThread *thread = new QThread;
|
QThread* thread = new QThread;
|
||||||
|
|
||||||
auto previewInputs = std::make_unique<std::vector<ComponentPreviewImagesDecorator::PreviewInput>>();
|
auto previewInputs = std::make_unique<std::vector<ComponentPreviewImagesDecorator::PreviewInput>>();
|
||||||
for (auto &component: m_document->componentMap) {
|
for (auto& component : m_document->componentMap) {
|
||||||
if (!component.second.isPreviewImageDecorationObsolete)
|
if (!component.second.isPreviewImageDecorationObsolete)
|
||||||
continue;
|
continue;
|
||||||
component.second.isPreviewImageDecorationObsolete = false;
|
component.second.isPreviewImageDecorationObsolete = false;
|
||||||
|
@ -1246,8 +1241,7 @@ void DocumentWindow::decorateComponentPreviewImages()
|
||||||
previewInputs->emplace_back(ComponentPreviewImagesDecorator::PreviewInput {
|
previewInputs->emplace_back(ComponentPreviewImagesDecorator::PreviewInput {
|
||||||
component.first,
|
component.first,
|
||||||
std::make_unique<QImage>(*component.second.previewImage),
|
std::make_unique<QImage>(*component.second.previewImage),
|
||||||
!component.second.childrenIds.empty()
|
!component.second.childrenIds.empty() });
|
||||||
});
|
|
||||||
}
|
}
|
||||||
m_componentPreviewImagesDecorator = std::make_unique<ComponentPreviewImagesDecorator>(std::move(previewInputs));
|
m_componentPreviewImagesDecorator = std::make_unique<ComponentPreviewImagesDecorator>(std::move(previewInputs));
|
||||||
m_componentPreviewImagesDecorator->moveToThread(thread);
|
m_componentPreviewImagesDecorator->moveToThread(thread);
|
||||||
|
@ -1264,7 +1258,7 @@ void DocumentWindow::componentPreviewImageDecorationsReady()
|
||||||
{
|
{
|
||||||
auto resultImages = m_componentPreviewImagesDecorator->takeResultImages();
|
auto resultImages = m_componentPreviewImagesDecorator->takeResultImages();
|
||||||
if (nullptr != resultImages) {
|
if (nullptr != resultImages) {
|
||||||
for (auto &it: *resultImages) {
|
for (auto& it : *resultImages) {
|
||||||
if (nullptr == it.second)
|
if (nullptr == it.second)
|
||||||
continue;
|
continue;
|
||||||
m_document->setComponentPreviewPixmap(it.first, QPixmap::fromImage(*it.second));
|
m_document->setComponentPreviewPixmap(it.first, QPixmap::fromImage(*it.second));
|
||||||
|
@ -1279,26 +1273,26 @@ void DocumentWindow::componentPreviewImageDecorationsReady()
|
||||||
updateInprogressIndicator();
|
updateInprogressIndicator();
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelWidget *DocumentWindow::modelWidget()
|
ModelWidget* DocumentWindow::modelWidget()
|
||||||
{
|
{
|
||||||
return m_modelRenderWidget;
|
return m_modelRenderWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
QShortcut *DocumentWindow::createShortcut(QKeySequence key)
|
QShortcut* DocumentWindow::createShortcut(QKeySequence key)
|
||||||
{
|
{
|
||||||
auto shortcutIt = m_shortcutMap.find(key);
|
auto shortcutIt = m_shortcutMap.find(key);
|
||||||
if (shortcutIt != m_shortcutMap.end())
|
if (shortcutIt != m_shortcutMap.end())
|
||||||
return shortcutIt->second;
|
return shortcutIt->second;
|
||||||
QShortcut *shortcut = new QShortcut(this);
|
QShortcut* shortcut = new QShortcut(this);
|
||||||
shortcut->setKey(key);
|
shortcut->setKey(key);
|
||||||
m_shortcutMap.insert({key, shortcut});
|
m_shortcutMap.insert({ key, shortcut });
|
||||||
return shortcut;
|
return shortcut;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define defineShortcut(keyVal, widget, funcName) \
|
#define defineShortcut(keyVal, widget, funcName) \
|
||||||
QObject::connect(createShortcut(keyVal), &QShortcut::activated, widget, funcName)
|
QObject::connect(createShortcut(keyVal), &QShortcut::activated, widget, funcName)
|
||||||
|
|
||||||
void DocumentWindow::initializeToolShortcuts(SkeletonGraphicsWidget *graphicsWidget)
|
void DocumentWindow::initializeToolShortcuts(SkeletonGraphicsWidget* graphicsWidget)
|
||||||
{
|
{
|
||||||
defineShortcut(Qt::Key_A, graphicsWidget, &SkeletonGraphicsWidget::shortcutAddMode);
|
defineShortcut(Qt::Key_A, graphicsWidget, &SkeletonGraphicsWidget::shortcutAddMode);
|
||||||
defineShortcut(Qt::CTRL + Qt::Key_A, graphicsWidget, &SkeletonGraphicsWidget::shortcutSelectAll);
|
defineShortcut(Qt::CTRL + Qt::Key_A, graphicsWidget, &SkeletonGraphicsWidget::shortcutSelectAll);
|
||||||
|
@ -1316,7 +1310,7 @@ void DocumentWindow::initializeToolShortcuts(SkeletonGraphicsWidget *graphicsWid
|
||||||
defineShortcut(Qt::Key_Escape, graphicsWidget, &SkeletonGraphicsWidget::shortcutEscape);
|
defineShortcut(Qt::Key_Escape, graphicsWidget, &SkeletonGraphicsWidget::shortcutEscape);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentWindow::initializeCanvasShortcuts(SkeletonGraphicsWidget *graphicsWidget)
|
void DocumentWindow::initializeCanvasShortcuts(SkeletonGraphicsWidget* graphicsWidget)
|
||||||
{
|
{
|
||||||
defineShortcut(Qt::Key_Delete, graphicsWidget, &SkeletonGraphicsWidget::shortcutDelete);
|
defineShortcut(Qt::Key_Delete, graphicsWidget, &SkeletonGraphicsWidget::shortcutDelete);
|
||||||
defineShortcut(Qt::Key_Backspace, graphicsWidget, &SkeletonGraphicsWidget::shortcutDelete);
|
defineShortcut(Qt::Key_Backspace, graphicsWidget, &SkeletonGraphicsWidget::shortcutDelete);
|
||||||
|
@ -1365,7 +1359,7 @@ void DocumentWindow::openRecentFile()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QAction *action = qobject_cast<QAction *>(sender());
|
QAction* action = qobject_cast<QAction*>(sender());
|
||||||
if (action) {
|
if (action) {
|
||||||
QString fileName = action->data().toString();
|
QString fileName = action->data().toString();
|
||||||
openPathAs(fileName, fileName);
|
openPathAs(fileName, fileName);
|
||||||
|
@ -1388,7 +1382,7 @@ void DocumentWindow::updateRecentFileActions()
|
||||||
m_recentFileSeparatorAction->setVisible(files.size() > 0);
|
m_recentFileSeparatorAction->setVisible(files.size() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString DocumentWindow::strippedName(const QString &fullFileName)
|
QString DocumentWindow::strippedName(const QString& fullFileName)
|
||||||
{
|
{
|
||||||
return QFileInfo(fullFileName).fileName();
|
return QFileInfo(fullFileName).fileName();
|
||||||
}
|
}
|
||||||
|
@ -1401,10 +1395,8 @@ bool DocumentWindow::isWorking()
|
||||||
void DocumentWindow::toggleRenderColor()
|
void DocumentWindow::toggleRenderColor()
|
||||||
{
|
{
|
||||||
m_modelRemoveColor = !m_modelRemoveColor;
|
m_modelRemoveColor = !m_modelRemoveColor;
|
||||||
ModelMesh *mesh = nullptr;
|
ModelMesh* mesh = nullptr;
|
||||||
if (m_document->isMeshGenerating() ||
|
if (m_document->isMeshGenerating() || m_document->isPostProcessing() || m_document->isTextureGenerating()) {
|
||||||
m_document->isPostProcessing() ||
|
|
||||||
m_document->isTextureGenerating()) {
|
|
||||||
mesh = m_document->takeResultMesh();
|
mesh = m_document->takeResultMesh();
|
||||||
} else {
|
} else {
|
||||||
mesh = m_document->takeResultTextureMesh();
|
mesh = m_document->takeResultTextureMesh();
|
||||||
|
|
|
@ -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;
|
QString m_currentFilename;
|
||||||
|
|
||||||
ModelWidget *m_modelRenderWidget = nullptr;
|
ModelWidget* m_modelRenderWidget = nullptr;
|
||||||
SkeletonGraphicsWidget *m_canvasGraphicsWidget = nullptr;
|
SkeletonGraphicsWidget* m_canvasGraphicsWidget = nullptr;
|
||||||
GraphicsContainerWidget *m_graphicsContainerWidget = nullptr;
|
GraphicsContainerWidget* m_graphicsContainerWidget = nullptr;
|
||||||
|
|
||||||
QMenu *m_fileMenu = nullptr;
|
QMenu* m_fileMenu = nullptr;
|
||||||
QAction *m_newWindowAction = nullptr;
|
QAction* m_newWindowAction = nullptr;
|
||||||
QAction *m_newDocumentAction = nullptr;
|
QAction* m_newDocumentAction = nullptr;
|
||||||
QAction *m_openAction = nullptr;
|
QAction* m_openAction = nullptr;
|
||||||
QMenu *m_openExampleMenu = nullptr;
|
QMenu* m_openExampleMenu = nullptr;
|
||||||
QAction *m_saveAction = nullptr;
|
QAction* m_saveAction = nullptr;
|
||||||
QAction *m_saveAsAction = nullptr;
|
QAction* m_saveAsAction = nullptr;
|
||||||
QAction *m_saveAllAction = nullptr;
|
QAction* m_saveAllAction = nullptr;
|
||||||
QAction *m_changeTurnaroundAction = nullptr;
|
QAction* m_changeTurnaroundAction = nullptr;
|
||||||
std::vector<QAction *> m_recentFileActions;
|
std::vector<QAction*> m_recentFileActions;
|
||||||
QAction *m_recentFileSeparatorAction = nullptr;
|
QAction* m_recentFileSeparatorAction = nullptr;
|
||||||
QAction *m_quitAction = nullptr;
|
QAction* m_quitAction = nullptr;
|
||||||
|
|
||||||
QAction *m_exportAsObjAction = nullptr;
|
QAction* m_exportAsObjAction = nullptr;
|
||||||
QAction *m_exportAsGlbAction = nullptr;
|
QAction* m_exportAsGlbAction = nullptr;
|
||||||
QAction *m_exportAsFbxAction = nullptr;
|
QAction* m_exportAsFbxAction = nullptr;
|
||||||
|
|
||||||
QMenu *m_viewMenu = nullptr;
|
QMenu* m_viewMenu = nullptr;
|
||||||
QAction *m_toggleWireframeAction = nullptr;
|
QAction* m_toggleWireframeAction = nullptr;
|
||||||
QAction *m_toggleRotationAction = nullptr;
|
QAction* m_toggleRotationAction = nullptr;
|
||||||
QAction *m_toggleColorAction = 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
|
||||||
|
|
||||||
|
|
|
@ -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,8 +27,8 @@ 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 ¤tDate = currentDateTime.date();
|
const auto& currentDate = currentDateTime.date();
|
||||||
const auto ¤tTime = 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);
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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();
|
||||||
|
@ -2223,16 +2223,16 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
|
||||||
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");
|
||||||
|
@ -2327,7 +2327,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
|
||||||
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);
|
||||||
{
|
{
|
||||||
|
@ -2402,11 +2402,10 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
|
||||||
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);
|
||||||
|
@ -2437,7 +2436,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
|
||||||
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");
|
||||||
|
@ -2837,7 +2836,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
|
||||||
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);
|
||||||
{
|
{
|
||||||
|
@ -2900,7 +2899,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
|
||||||
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);
|
||||||
{
|
{
|
||||||
|
@ -3104,7 +3103,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
|
||||||
}
|
}
|
||||||
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);
|
||||||
|
@ -3214,36 +3213,36 @@ 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");
|
||||||
}
|
}
|
||||||
|
@ -3267,7 +3266,7 @@ FbxFileWriter::FbxFileWriter(dust3d::Object &object,
|
||||||
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,32 +3275,32 @@ 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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());
|
||||||
|
|
|
@ -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,15 +30,15 @@ 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;
|
||||||
|
@ -51,4 +50,3 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
@ -20,7 +20,7 @@ FloatNumberWidget::FloatNumberWidget(QWidget *parent, bool singleLine) :
|
||||||
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());
|
||||||
|
|
|
@ -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:
|
||||||
|
@ -28,8 +27,8 @@ 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -53,13 +53,13 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object,
|
||||||
|
|
||||||
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]]);
|
||||||
|
@ -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)
|
||||||
|
@ -150,8 +150,8 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object,
|
||||||
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) {
|
||||||
|
@ -159,8 +159,8 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object,
|
||||||
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())));
|
||||||
|
@ -184,8 +184,8 @@ GlbFileWriter::GlbFileWriter(dust3d::Object &object,
|
||||||
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;
|
||||||
|
@ -291,9 +291,7 @@ bool GlbFileWriter::save()
|
||||||
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();
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,31 +5,31 @@ 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);
|
||||||
|
@ -40,12 +40,12 @@ void GraphicsContainerWidget::wheelEvent(QWheelEvent *event)
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
class HorizontalLineWidget : public QWidget
|
class HorizontalLineWidget : public QWidget {
|
||||||
{
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
HorizontalLineWidget();
|
HorizontalLineWidget();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#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);
|
||||||
|
@ -11,7 +11,7 @@ InfoLabel::InfoLabel(const QString &text, QWidget *parent) :
|
||||||
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();
|
||||||
|
@ -19,7 +19,7 @@ InfoLabel::InfoLabel(const QString &text, QWidget *parent) :
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InfoLabel::setText(const QString &text)
|
void InfoLabel::setText(const QString& text)
|
||||||
{
|
{
|
||||||
m_label->setText(text);
|
m_label->setText(text);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
@ -19,7 +19,7 @@ IntNumberWidget::IntNumberWidget(QWidget *parent, bool singleLine) :
|
||||||
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());
|
||||||
|
|
|
@ -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();
|
||||||
|
@ -27,8 +26,8 @@ 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#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;
|
||||||
|
@ -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());
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
@ -47,14 +47,11 @@ LogBrowserDialog::LogBrowserDialog(QWidget *parent) :
|
||||||
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,
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
#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);
|
||||||
|
|
||||||
|
@ -27,15 +27,14 @@ int main(int argc, char *argv[])
|
||||||
//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]);
|
||||||
|
@ -60,7 +59,7 @@ int main(int argc, char *argv[])
|
||||||
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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -1,46 +1,46 @@
|
||||||
#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);
|
||||||
|
|
||||||
|
@ -56,19 +56,19 @@ MaterialEditWidget::MaterialEditWidget(const Document *document, QWidget *parent
|
||||||
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);
|
||||||
|
@ -77,10 +77,10 @@ MaterialEditWidget::MaterialEditWidget(const Document *document, QWidget *parent
|
||||||
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, [=]() {
|
||||||
|
@ -89,7 +89,7 @@ MaterialEditWidget::MaterialEditWidget(const Document *document, QWidget *parent
|
||||||
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();
|
||||||
|
@ -105,12 +105,12 @@ MaterialEditWidget::MaterialEditWidget(const Document *document, QWidget *parent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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,11 +120,11 @@ 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);
|
||||||
|
@ -136,25 +136,25 @@ MaterialEditWidget::MaterialEditWidget(const Document *document, QWidget *parent
|
||||||
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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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())
|
||||||
|
@ -249,9 +248,9 @@ void MaterialListWidget::reload()
|
||||||
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();
|
||||||
|
@ -304,6 +303,6 @@ void MaterialListWidget::copy()
|
||||||
|
|
||||||
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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,63 +16,63 @@ 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();
|
||||||
|
@ -80,14 +80,14 @@ void MaterialPreviewsGenerator::generate()
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -36,22 +36,21 @@ void MeshGenerator::process()
|
||||||
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,
|
||||||
|
@ -76,8 +75,7 @@ void MeshGenerator::process()
|
||||||
emit finished();
|
emit finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelMesh *MeshGenerator::takeResultMesh()
|
ModelMesh* MeshGenerator::takeResultMesh()
|
||||||
{
|
{
|
||||||
return m_resultMesh.release();
|
return m_resultMesh.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#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()
|
||||||
|
@ -14,7 +14,7 @@ void MeshPreviewImagesGenerator::process()
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ void MeshPreviewImagesGenerator::generate()
|
||||||
|
|
||||||
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);
|
||||||
|
|
|
@ -1,24 +1,22 @@
|
||||||
#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;
|
||||||
};
|
};
|
||||||
|
@ -28,16 +26,17 @@ public:
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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++)
|
||||||
|
@ -54,27 +53,27 @@ void ModelMesh::removeColor()
|
||||||
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,19 +116,19 @@ 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;
|
||||||
|
@ -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,7 +331,7 @@ 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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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";
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
#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();
|
||||||
|
@ -23,8 +22,8 @@ public:
|
||||||
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;
|
||||||
|
|
|
@ -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,8 +18,8 @@ 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);
|
||||||
|
@ -37,17 +37,17 @@ ModelWidget::ModelWidget(QWidget *parent) :
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,7 @@ void ModelWidget::resizeGL(int w, int h)
|
||||||
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,7 +234,7 @@ 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);
|
||||||
|
|
||||||
|
@ -251,8 +250,7 @@ bool ModelWidget::inputMouseMoveEventFromOtherWidget(QMouseEvent *event)
|
||||||
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) {
|
||||||
|
@ -287,12 +285,12 @@ bool ModelWidget::inputMouseMoveEventFromOtherWidget(QMouseEvent *event)
|
||||||
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;
|
||||||
|
@ -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>();
|
||||||
|
@ -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>();
|
||||||
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
@ -147,13 +147,12 @@ void PartManageWidget::showSelectedComponentProperties()
|
||||||
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();
|
||||||
});
|
});
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
#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,7 +40,7 @@ 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();
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -206,8 +206,7 @@ void SkeletonDocument::removeEdge(dust3d::Uuid 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);
|
||||||
|
@ -218,13 +217,13 @@ void SkeletonDocument::removeEdge(dust3d::Uuid edgeId)
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -279,8 +278,7 @@ void SkeletonDocument::removeNode(dust3d::Uuid 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);
|
||||||
|
@ -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);
|
||||||
|
@ -355,11 +353,11 @@ dust3d::Uuid SkeletonDocument::createNode(dust3d::Uuid nodeId, float x, float y,
|
||||||
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,7 +408,7 @@ 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()) {
|
||||||
|
@ -420,7 +418,7 @@ const SkeletonComponent *SkeletonDocument::findComponentParent(dust3d::Uuid comp
|
||||||
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
|
||||||
|
@ -435,7 +433,7 @@ dust3d::Uuid SkeletonDocument::findComponentParentId(dust3d::Uuid componentId) c
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
@ -449,7 +447,7 @@ 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;
|
||||||
|
|
||||||
|
@ -463,7 +461,7 @@ 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;
|
||||||
|
|
||||||
|
@ -477,7 +475,7 @@ 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;
|
||||||
|
|
||||||
|
@ -520,11 +518,11 @@ void SkeletonDocument::setComponentExpandState(dust3d::Uuid componentId, bool ex
|
||||||
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,10 +592,10 @@ 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());
|
||||||
|
@ -659,10 +657,10 @@ void SkeletonDocument::removePartDontCareComponent(dust3d::Uuid partId)
|
||||||
|
|
||||||
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);
|
||||||
|
@ -712,7 +710,7 @@ void SkeletonDocument::removeComponentRecursively(dust3d::Uuid componentId)
|
||||||
}
|
}
|
||||||
|
|
||||||
auto childrenIds = component->second.childrenIds;
|
auto childrenIds = component->second.childrenIds;
|
||||||
for (const auto &childId: childrenIds) {
|
for (const auto& childId : childrenIds) {
|
||||||
removeComponentRecursively(childId);
|
removeComponentRecursively(childId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -770,7 +768,7 @@ void SkeletonDocument::addComponent(dust3d::Uuid parentId)
|
||||||
|
|
||||||
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;
|
||||||
|
@ -864,9 +862,9 @@ 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;
|
||||||
|
|
||||||
|
@ -875,14 +873,14 @@ void SkeletonDocument::collectComponentDescendantParts(dust3d::Uuid componentId,
|
||||||
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;
|
||||||
|
@ -1167,8 +1165,8 @@ void SkeletonDocument::addEdge(dust3d::Uuid fromNodeId, dust3d::Uuid 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);
|
||||||
|
@ -1239,21 +1237,21 @@ void SkeletonDocument::addEdge(dust3d::Uuid fromNodeId, dust3d::Uuid toNodeId)
|
||||||
|
|
||||||
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));
|
||||||
|
|
|
@ -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);
|
||||||
|
@ -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,19 +601,19 @@ 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();
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -746,9 +743,9 @@ private:
|
||||||
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
|
@ -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");
|
||||||
}
|
}
|
||||||
|
@ -38,8 +37,7 @@ public:
|
||||||
{
|
{
|
||||||
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:
|
||||||
|
@ -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);
|
||||||
|
@ -147,8 +144,7 @@ public:
|
||||||
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:
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -317,8 +313,7 @@ public:
|
||||||
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:
|
||||||
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -122,17 +122,17 @@ void TextureGenerator::prepare()
|
||||||
|
|
||||||
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);
|
||||||
|
@ -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);
|
||||||
|
@ -193,26 +193,26 @@ void TextureGenerator::generate()
|
||||||
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);
|
||||||
|
@ -260,15 +260,15 @@ void TextureGenerator::generate()
|
||||||
|
|
||||||
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,
|
||||||
|
@ -280,19 +280,19 @@ 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,
|
||||||
|
@ -305,19 +305,19 @@ 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,
|
||||||
|
@ -330,24 +330,24 @@ 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,
|
||||||
|
@ -365,11 +365,11 @@ 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();
|
||||||
|
@ -400,34 +400,33 @@ void TextureGenerator::generate()
|
||||||
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,8 +444,8 @@ 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);
|
||||||
|
@ -493,7 +492,7 @@ 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,13 +503,13 @@ 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);
|
||||||
|
@ -520,22 +519,22 @@ void TextureGenerator::generate()
|
||||||
// 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;
|
||||||
|
@ -544,23 +543,21 @@ void TextureGenerator::generate()
|
||||||
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),
|
||||||
|
@ -581,26 +578,26 @@ void TextureGenerator::generate()
|
||||||
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),
|
||||||
|
@ -664,14 +661,12 @@ void TextureGenerator::generate()
|
||||||
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();
|
||||||
|
|
|
@ -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
Loading…
Reference in New Issue