Make a abstract class for document: SkeletonDocument

This is mainly for reusing the SkeletonGraphicsEditWidget for other purpose, such as the new pose editor.
master
Jeremy Hu 2018-11-03 16:09:42 +08:00
parent e7249db089
commit a4aefdd308
10 changed files with 412 additions and 373 deletions

View File

@ -291,6 +291,9 @@ HEADERS += src/riggerconstruct.h
SOURCES += src/poserconstruct.cpp
HEADERS += src/poserconstruct.h
SOURCES += src/skeletondocument.cpp
HEADERS += src/skeletondocument.h
SOURCES += src/main.cpp
HEADERS += src/version.h

View File

@ -17,15 +17,8 @@
unsigned long Document::m_maxSnapshot = 1000;
Document::Document() :
SkeletonDocument(),
// public
originX(0),
originY(0),
originZ(0),
editMode(DocumentEditMode::Select),
xlocked(false),
ylocked(false),
zlocked(false),
radiusLocked(false),
textureGuideImage(nullptr),
textureImage(nullptr),
textureBorderImage(nullptr),
@ -92,7 +85,7 @@ void Document::Document::disableAllPositionRelatedLocks()
void Document::breakEdge(QUuid edgeId)
{
const Edge *edge = findEdge(edgeId);
const SkeletonEdge *edge = findEdge(edgeId);
if (nullptr == edge) {
qDebug() << "Find edge failed:" << edgeId;
return;
@ -102,12 +95,12 @@ void Document::breakEdge(QUuid edgeId)
}
QUuid firstNodeId = edge->nodeIds[0];
QUuid secondNodeId = edge->nodeIds[1];
const Node *firstNode = findNode(firstNodeId);
const SkeletonNode *firstNode = findNode(firstNodeId);
if (nullptr == firstNode) {
qDebug() << "Find node failed:" << firstNodeId;
return;
}
const Node *secondNode = findNode(secondNodeId);
const SkeletonNode *secondNode = findNode(secondNodeId);
if (nullptr == secondNode) {
qDebug() << "Find node failed:" << secondNodeId;
return;
@ -127,14 +120,14 @@ void Document::breakEdge(QUuid edgeId)
void Document::removeEdge(QUuid edgeId)
{
const Edge *edge = findEdge(edgeId);
const SkeletonEdge *edge = findEdge(edgeId);
if (nullptr == edge) {
qDebug() << "Find edge failed:" << edgeId;
return;
}
if (isPartReadonly(edge->partId))
return;
const Part *oldPart = findPart(edge->partId);
const SkeletonPart *oldPart = findPart(edge->partId);
if (nullptr == oldPart) {
qDebug() << "Find part failed:" << edge->partId;
return;
@ -145,7 +138,7 @@ void Document::removeEdge(QUuid edgeId)
splitPartByEdge(&groups, edgeId);
for (auto groupIt = groups.begin(); groupIt != groups.end(); groupIt++) {
const auto newUuid = QUuid::createUuid();
Part &part = partMap[newUuid];
SkeletonPart &part = partMap[newUuid];
part.id = newUuid;
part.copyAttributes(*oldPart);
part.name = nextPartName;
@ -187,14 +180,14 @@ void Document::removeEdge(QUuid edgeId)
void Document::removeNode(QUuid nodeId)
{
const Node *node = findNode(nodeId);
const SkeletonNode *node = findNode(nodeId);
if (nullptr == node) {
qDebug() << "Find node failed:" << nodeId;
return;
}
if (isPartReadonly(node->partId))
return;
const Part *oldPart = findPart(node->partId);
const SkeletonPart *oldPart = findPart(node->partId);
if (nullptr == oldPart) {
qDebug() << "Find part failed:" << node->partId;
return;
@ -205,7 +198,7 @@ void Document::removeNode(QUuid nodeId)
splitPartByNode(&groups, nodeId);
for (auto groupIt = groups.begin(); groupIt != groups.end(); groupIt++) {
const auto newUuid = QUuid::createUuid();
Part &part = partMap[newUuid];
SkeletonPart &part = partMap[newUuid];
part.id = newUuid;
part.copyAttributes(*oldPart);
part.name = nextPartName;
@ -260,11 +253,11 @@ void Document::addNode(float x, float y, float z, float radius, QUuid fromNodeId
QUuid Document::createNode(float x, float y, float z, float radius, QUuid fromNodeId)
{
QUuid partId;
const Node *fromNode = nullptr;
const SkeletonNode *fromNode = nullptr;
bool newPartAdded = false;
if (fromNodeId.isNull()) {
const auto newUuid = QUuid::createUuid();
Part &part = partMap[newUuid];
SkeletonPart &part = partMap[newUuid];
part.id = newUuid;
partId = part.id;
emit partAdded(partId);
@ -282,7 +275,7 @@ QUuid Document::createNode(float x, float y, float z, float radius, QUuid fromNo
if (part != partMap.end())
part->second.dirty = true;
}
Node node;
SkeletonNode node;
node.partId = partId;
node.setRadius(radius);
node.x = x;
@ -294,7 +287,7 @@ QUuid Document::createNode(float x, float y, float z, float radius, QUuid fromNo
emit nodeAdded(node.id);
if (nullptr != fromNode) {
Edge edge;
SkeletonEdge edge;
edge.partId = partId;
edge.nodeIds.push_back(fromNode->id);
edge.nodeIds.push_back(node.id);
@ -438,9 +431,9 @@ void Document::renamePose(QUuid poseId, QString name)
emit optionsChanged();
}
const Edge *Document::findEdgeByNodes(QUuid firstNodeId, QUuid secondNodeId) const
const SkeletonEdge *Document::findEdgeByNodes(QUuid firstNodeId, QUuid secondNodeId) const
{
const Node *firstNode = nullptr;
const SkeletonNode *firstNode = nullptr;
firstNode = findNode(firstNodeId);
if (nullptr == firstNode) {
qDebug() << "Find node failed:" << firstNodeId;
@ -470,8 +463,8 @@ void Document::addEdge(QUuid fromNodeId, QUuid toNodeId)
return;
}
const Node *fromNode = nullptr;
const Node *toNode = nullptr;
const SkeletonNode *fromNode = nullptr;
const SkeletonNode *toNode = nullptr;
bool toPartRemoved = false;
fromNode = findNode(fromNodeId);
@ -526,7 +519,7 @@ void Document::addEdge(QUuid fromNodeId, QUuid toNodeId)
}
}
Edge edge;
SkeletonEdge edge;
edge.partId = fromNode->partId;
edge.nodeIds.push_back(fromNode->id);
edge.nodeIds.push_back(toNodeId);
@ -544,7 +537,7 @@ void Document::addEdge(QUuid fromNodeId, QUuid toNodeId)
emit skeletonChanged();
}
const Node *Document::findNode(QUuid nodeId) const
const SkeletonNode *Document::findNode(QUuid nodeId) const
{
auto it = nodeMap.find(nodeId);
if (it == nodeMap.end())
@ -552,7 +545,7 @@ const Node *Document::findNode(QUuid nodeId) const
return &it->second;
}
const Edge *Document::findEdge(QUuid edgeId) const
const SkeletonEdge *Document::findEdge(QUuid edgeId) const
{
auto it = edgeMap.find(edgeId);
if (it == edgeMap.end())
@ -560,7 +553,7 @@ const Edge *Document::findEdge(QUuid edgeId) const
return &it->second;
}
const Part *Document::findPart(QUuid partId) const
const SkeletonPart *Document::findPart(QUuid partId) const
{
auto it = partMap.find(partId);
if (it == partMap.end())
@ -623,7 +616,7 @@ void Document::scaleNodeByAddRadius(QUuid nodeId, float amount)
bool Document::isPartReadonly(QUuid partId) const
{
const Part *part = findPart(partId);
const SkeletonPart *part = findPart(partId);
if (nullptr == part) {
qDebug() << "Find part failed:" << partId;
return true;
@ -757,7 +750,7 @@ void Document::updateTurnaround(const QImage &image)
emit turnaroundChanged();
}
void Document::setEditMode(DocumentEditMode mode)
void Document::setEditMode(SkeletonDocumentEditMode mode)
{
if (editMode == mode)
return;
@ -770,7 +763,7 @@ void Document::joinNodeAndNeiborsToGroup(std::vector<QUuid> *group, QUuid nodeId
{
if (nodeId.isNull() || visitMap->find(nodeId) != visitMap->end())
return;
const Node *node = findNode(nodeId);
const SkeletonNode *node = findNode(nodeId);
if (nullptr == node) {
qDebug() << "Find node failed:" << nodeId;
return;
@ -780,7 +773,7 @@ void Document::joinNodeAndNeiborsToGroup(std::vector<QUuid> *group, QUuid nodeId
for (auto edgeIt = node->edgeIds.begin(); edgeIt != node->edgeIds.end(); edgeIt++) {
if (noUseEdgeId == *edgeIt)
continue;
const Edge *edge = findEdge(*edgeIt);
const SkeletonEdge *edge = findEdge(*edgeIt);
if (nullptr == edge) {
qDebug() << "Find edge failed:" << *edgeIt;
continue;
@ -793,11 +786,11 @@ void Document::joinNodeAndNeiborsToGroup(std::vector<QUuid> *group, QUuid nodeId
void Document::splitPartByNode(std::vector<std::vector<QUuid>> *groups, QUuid nodeId)
{
const Node *node = findNode(nodeId);
const SkeletonNode *node = findNode(nodeId);
std::set<QUuid> visitMap;
for (auto edgeIt = node->edgeIds.begin(); edgeIt != node->edgeIds.end(); edgeIt++) {
std::vector<QUuid> group;
const Edge *edge = findEdge(*edgeIt);
const SkeletonEdge *edge = findEdge(*edgeIt);
if (nullptr == edge) {
qDebug() << "Find edge failed:" << *edgeIt;
continue;
@ -810,7 +803,7 @@ void Document::splitPartByNode(std::vector<std::vector<QUuid>> *groups, QUuid no
void Document::splitPartByEdge(std::vector<std::vector<QUuid>> *groups, QUuid edgeId)
{
const Edge *edge = findEdge(edgeId);
const SkeletonEdge *edge = findEdge(edgeId);
if (nullptr == edge) {
qDebug() << "Find edge failed:" << edgeId;
return;
@ -852,10 +845,10 @@ void Document::toSnapshot(Snapshot *snapshot, const std::set<QUuid> &limitNodeId
std::set<QUuid> limitPartIds;
std::set<QUuid> limitComponentIds;
for (const auto &nodeId: limitNodeIds) {
const Node *node = findNode(nodeId);
const SkeletonNode *node = findNode(nodeId);
if (!node)
continue;
const Part *part = findPart(node->partId);
const SkeletonPart *part = findPart(node->partId);
if (!part)
continue;
limitPartIds.insert(node->partId);
@ -1121,7 +1114,7 @@ void Document::addFromSnapshot(const Snapshot &snapshot, bool fromPaste)
}
for (const auto &partKv: snapshot.parts) {
const auto newUuid = QUuid::createUuid();
Part &part = partMap[newUuid];
SkeletonPart &part = partMap[newUuid];
part.id = newUuid;
oldNewIdMap[QUuid(partKv.first)] = part.id;
part.name = valueOfKeyInMapOrEmpty(partKv.second, "name");
@ -1158,7 +1151,7 @@ void Document::addFromSnapshot(const Snapshot &snapshot, bool fromPaste)
nodeKv.second.find("z") == nodeKv.second.end() ||
nodeKv.second.find("partId") == nodeKv.second.end())
continue;
Node node;
SkeletonNode node;
oldNewIdMap[QUuid(nodeKv.first)] = node.id;
node.name = valueOfKeyInMapOrEmpty(nodeKv.second, "name");
node.radius = valueOfKeyInMapOrEmpty(nodeKv.second, "radius").toFloat();
@ -1175,7 +1168,7 @@ void Document::addFromSnapshot(const Snapshot &snapshot, bool fromPaste)
edgeKv.second.find("to") == edgeKv.second.end() ||
edgeKv.second.find("partId") == edgeKv.second.end())
continue;
Edge edge;
SkeletonEdge edge;
oldNewIdMap[QUuid(edgeKv.first)] = edge.id;
edge.name = valueOfKeyInMapOrEmpty(edgeKv.second, "name");
edge.partId = oldNewIdMap[QUuid(valueOfKeyInMapOrEmpty(edgeKv.second, "partId"))];
@ -2330,7 +2323,7 @@ bool Document::redoable() const
bool Document::isNodeEditable(QUuid nodeId) const
{
const Node *node = findNode(nodeId);
const SkeletonNode *node = findNode(nodeId);
if (!node) {
qDebug() << "Node id not found:" << nodeId;
return false;
@ -2340,7 +2333,7 @@ bool Document::isNodeEditable(QUuid nodeId) const
bool Document::isEdgeEditable(QUuid edgeId) const
{
const Edge *edge = findEdge(edgeId);
const SkeletonEdge *edge = findEdge(edgeId);
if (!edge) {
qDebug() << "Edge id not found:" << edgeId;
return false;
@ -2943,3 +2936,13 @@ bool Document::isMeshGenerating() const
return nullptr != m_meshGenerator;
}
void Document::copyNodes(std::set<QUuid> nodeIdSet) const
{
Snapshot snapshot;
toSnapshot(&snapshot, nodeIdSet, DocumentToSnapshotFor::Nodes);
QString snapshotXml;
QXmlStreamWriter xmlStreamWriter(&snapshotXml);
saveSkeletonToXmlStream(&snapshot, &xmlStreamWriter);
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(snapshotXml);
}

View File

@ -23,179 +23,11 @@
#include "texturetype.h"
#include "interpolationtype.h"
#include "jointnodetree.h"
#include "skeletondocument.h"
class MaterialPreviewsGenerator;
class MotionsGenerator;
class Node
{
public:
Node(const QUuid &withId=QUuid()) :
x(0),
y(0),
z(0),
radius(0),
boneMark(BoneMark::None)
{
id = withId.isNull() ? QUuid::createUuid() : withId;
}
void setRadius(float toRadius)
{
if (toRadius < 0)
toRadius = 0.005;
else if (toRadius > 1)
toRadius = 1;
radius = toRadius;
}
QUuid id;
QUuid partId;
QString name;
float x;
float y;
float z;
float radius;
BoneMark boneMark;
std::vector<QUuid> edgeIds;
};
class Edge
{
public:
Edge(const QUuid &withId=QUuid())
{
id = withId.isNull() ? QUuid::createUuid() : withId;
}
QUuid id;
QUuid partId;
QString name;
std::vector<QUuid> nodeIds;
QUuid neighborOf(QUuid nodeId) const
{
if (nodeIds.size() != 2)
return QUuid();
return nodeIds[0] == nodeId ? nodeIds[1] : nodeIds[0];
}
};
class Part
{
public:
~Part()
{
delete m_previewMesh;
}
QUuid id;
QString name;
bool visible;
bool locked;
bool subdived;
bool disabled;
bool xMirrored;
bool zMirrored;
float deformThickness;
float deformWidth;
bool rounded;
QColor color;
bool hasColor;
QUuid componentId;
std::vector<QUuid> nodeIds;
bool dirty;
bool wrapped;
QUuid materialId;
Part(const QUuid &withId=QUuid()) :
visible(true),
locked(false),
subdived(false),
disabled(false),
xMirrored(false),
zMirrored(false),
deformThickness(1.0),
deformWidth(1.0),
rounded(false),
color(Theme::white),
hasColor(false),
dirty(true),
wrapped(false)
{
id = withId.isNull() ? QUuid::createUuid() : withId;
}
void setDeformThickness(float toThickness)
{
if (toThickness < 0)
toThickness = 0;
else if (toThickness > 2)
toThickness = 2;
deformThickness = toThickness;
}
void setDeformWidth(float toWidth)
{
if (toWidth < 0)
toWidth = 0;
else if (toWidth > 2)
toWidth = 2;
deformWidth = toWidth;
}
bool deformThicknessAdjusted() const
{
return fabs(deformThickness - 1.0) >= 0.01;
}
bool deformWidthAdjusted() const
{
return fabs(deformWidth - 1.0) >= 0.01;
}
bool deformAdjusted() const
{
return deformThicknessAdjusted() || deformWidthAdjusted();
}
bool materialAdjusted() const
{
return !materialId.isNull();
}
bool isEditVisible() const
{
return visible && !disabled;
}
void copyAttributes(const Part &other)
{
visible = other.visible;
locked = other.locked;
subdived = other.subdived;
disabled = other.disabled;
xMirrored = other.xMirrored;
zMirrored = other.zMirrored;
deformThickness = other.deformThickness;
deformWidth = other.deformWidth;
rounded = other.rounded;
color = other.color;
hasColor = other.hasColor;
wrapped = other.wrapped;
componentId = other.componentId;
dirty = other.dirty;
materialId = other.materialId;
}
void updatePreviewMesh(MeshLoader *previewMesh)
{
delete m_previewMesh;
m_previewMesh = previewMesh;
}
MeshLoader *takePreviewMesh() const
{
if (nullptr == m_previewMesh)
return nullptr;
return new MeshLoader(*m_previewMesh);
}
private:
Q_DISABLE_COPY(Part);
MeshLoader *m_previewMesh = nullptr;
};
enum class SkeletonProfile
{
Unknown = 0,
Main,
Side
};
class HistoryItem
{
public:
@ -203,15 +35,6 @@ public:
Snapshot snapshot;
};
enum class DocumentEditMode
{
Add = 0,
Select,
Drag,
ZoomIn,
ZoomOut
};
class Component
{
public:
@ -532,7 +355,7 @@ enum class DocumentToSnapshotFor
Motions
};
class Document : public QObject
class Document : public SkeletonDocument
{
Q_OBJECT
signals:
@ -620,14 +443,6 @@ signals:
void textureGenerating();
void textureChanged();
public: // need initialize
float originX;
float originY;
float originZ;
DocumentEditMode editMode;
bool xlocked;
bool ylocked;
bool zlocked;
bool radiusLocked;
QImage *textureGuideImage;
QImage *textureImage;
QImage *textureBorderImage;
@ -638,9 +453,9 @@ public: // need initialize
public:
Document();
~Document();
std::map<QUuid, Part> partMap;
std::map<QUuid, Node> nodeMap;
std::map<QUuid, Edge> edgeMap;
std::map<QUuid, SkeletonPart> partMap;
std::map<QUuid, SkeletonNode> nodeMap;
std::map<QUuid, SkeletonEdge> edgeMap;
std::map<QUuid, Component> componentMap;
std::map<QUuid, Material> materialMap;
std::vector<QUuid> materialIdList;
@ -649,8 +464,19 @@ public:
std::map<QUuid, Motion> motionMap;
std::vector<QUuid> motionIdList;
Component rootComponent;
QImage turnaround;
QImage preview;
const SkeletonNode *findNode(QUuid nodeId) const override;
const SkeletonEdge *findEdge(QUuid edgeId) const override;
const SkeletonPart *findPart(QUuid partId) const override;
const SkeletonEdge *findEdgeByNodes(QUuid firstNodeId, QUuid secondNodeId) const override;
bool undoable() const override;
bool redoable() const override;
bool hasPastableNodesInClipboard() const override;
bool originSettled() const override;
bool isNodeEditable(QUuid nodeId) const override;
bool isEdgeEditable(QUuid edgeId) const override;
void findAllNeighbors(QUuid nodeId, std::set<QUuid> &neighbors) const override;
void copyNodes(std::set<QUuid> nodeIdSet) const override;
void toSnapshot(Snapshot *snapshot, const std::set<QUuid> &limitNodeIds=std::set<QUuid>(),
DocumentToSnapshotFor forWhat=DocumentToSnapshotFor::Document,
const std::set<QUuid> &limitPoseIds=std::set<QUuid>(),
@ -658,10 +484,6 @@ public:
const std::set<QUuid> &limitMaterialIds=std::set<QUuid>()) const;
void fromSnapshot(const Snapshot &snapshot);
void addFromSnapshot(const Snapshot &snapshot, bool fromPaste=true);
const Node *findNode(QUuid nodeId) const;
const Edge *findEdge(QUuid edgeId) const;
const Part *findPart(QUuid partId) const;
const Edge *findEdgeByNodes(QUuid firstNodeId, QUuid secondNodeId) const;
const Component *findComponent(QUuid componentId) const;
const Component *findComponentParent(QUuid componentId) const;
QUuid findComponentParentId(QUuid componentId) const;
@ -675,19 +497,12 @@ public:
const std::map<int, RiggerVertexWeights> *resultRigWeights() const;
void updateTurnaround(const QImage &image);
void setSharedContextWidget(QOpenGLWidget *sharedContextWidget);
bool hasPastableNodesInClipboard() const;
bool hasPastableMaterialsInClipboard() const;
bool hasPastablePosesInClipboard() const;
bool hasPastableMotionsInClipboard() const;
bool undoable() const;
bool redoable() const;
bool isNodeEditable(QUuid nodeId) const;
bool isEdgeEditable(QUuid edgeId) const;
bool originSettled() const;
const Outcome &currentPostProcessedOutcome() const;
bool isExportReady() const;
bool isPostProcessResultObsolete() const;
void findAllNeighbors(QUuid nodeId, std::set<QUuid> &neighbors) const;
void collectComponentDescendantParts(QUuid componentId, std::vector<QUuid> &partIds) const;
void collectComponentDescendantComponents(QUuid componentId, std::vector<QUuid> &componentIds) const;
const std::vector<QString> &resultRigMissingMarkNames() const;
@ -696,6 +511,9 @@ public:
bool currentRigSucceed() const;
bool isMeshGenerating() const;
public slots:
void undo() override;
void redo() override;
void paste() override;
void removeNode(QUuid nodeId);
void removeEdge(QUuid edgeId);
void removePart(QUuid partId);
@ -708,7 +526,7 @@ public slots:
void switchNodeXZ(QUuid nodeId);
void moveOriginBy(float x, float y, float z);
void addEdge(QUuid fromNodeId, QUuid toNodeId);
void setEditMode(DocumentEditMode mode);
void setEditMode(SkeletonDocumentEditMode mode);
void uiReady();
void generateMesh();
void regenerateMesh();
@ -765,9 +583,6 @@ public slots:
void lockDescendantComponents(QUuid componentId);
void unlockDescendantComponents(QUuid componentId);
void saveSnapshot();
void undo();
void redo();
void paste();
void batchChangeBegin();
void batchChangeEnd();
void reset();

View File

@ -371,7 +371,7 @@ SkeletonDocumentWindow::SkeletonDocumentWindow() :
m_addAction = new QAction(tr("Add..."), this);
connect(m_addAction, &QAction::triggered, [=]() {
m_document->setEditMode(DocumentEditMode::Add);
m_document->setEditMode(SkeletonDocumentEditMode::Add);
});
m_editMenu->addAction(m_addAction);
@ -657,23 +657,23 @@ SkeletonDocumentWindow::SkeletonDocumentWindow() :
connect(rotateClockwiseButton, &QPushButton::clicked, graphicsWidget, &SkeletonGraphicsWidget::rotateAllMainProfileClockwise90DegreeAlongOrigin);
connect(addButton, &QPushButton::clicked, [=]() {
m_document->setEditMode(DocumentEditMode::Add);
m_document->setEditMode(SkeletonDocumentEditMode::Add);
});
connect(selectButton, &QPushButton::clicked, [=]() {
m_document->setEditMode(DocumentEditMode::Select);
m_document->setEditMode(SkeletonDocumentEditMode::Select);
});
connect(dragButton, &QPushButton::clicked, [=]() {
m_document->setEditMode(DocumentEditMode::Drag);
m_document->setEditMode(SkeletonDocumentEditMode::Drag);
});
connect(zoomInButton, &QPushButton::clicked, [=]() {
m_document->setEditMode(DocumentEditMode::ZoomIn);
m_document->setEditMode(SkeletonDocumentEditMode::ZoomIn);
});
connect(zoomOutButton, &QPushButton::clicked, [=]() {
m_document->setEditMode(DocumentEditMode::ZoomOut);
m_document->setEditMode(SkeletonDocumentEditMode::ZoomOut);
});
connect(m_xlockButton, &QPushButton::clicked, [=]() {

View File

@ -193,7 +193,7 @@ void PartTreeWidget::mousePressEvent(QMouseEvent *event)
void PartTreeWidget::showContextMenu(const QPoint &pos)
{
const Component *component = nullptr;
const Part *part = nullptr;
const SkeletonPart *part = nullptr;
PartWidget *partWidget = nullptr;
std::set<QUuid> unorderedComponentIds = m_selectedComponentIds;

View File

@ -143,7 +143,7 @@ PartWidget::PartWidget(const Document *document, QUuid partId) :
connect(this, &PartWidget::groupOperationAdded, m_document, &Document::saveSnapshot);
connect(m_lockButton, &QPushButton::clicked, [=]() {
const Part *part = m_document->findPart(m_partId);
const SkeletonPart *part = m_document->findPart(m_partId);
if (!part) {
qDebug() << "Part not found:" << m_partId;
return;
@ -153,7 +153,7 @@ PartWidget::PartWidget(const Document *document, QUuid partId) :
});
connect(m_visibleButton, &QPushButton::clicked, [=]() {
const Part *part = m_document->findPart(m_partId);
const SkeletonPart *part = m_document->findPart(m_partId);
if (!part) {
qDebug() << "Part not found:" << m_partId;
return;
@ -163,7 +163,7 @@ PartWidget::PartWidget(const Document *document, QUuid partId) :
});
connect(m_subdivButton, &QPushButton::clicked, [=]() {
const Part *part = m_document->findPart(m_partId);
const SkeletonPart *part = m_document->findPart(m_partId);
if (!part) {
qDebug() << "Part not found:" << m_partId;
return;
@ -173,7 +173,7 @@ PartWidget::PartWidget(const Document *document, QUuid partId) :
});
connect(m_disableButton, &QPushButton::clicked, [=]() {
const Part *part = m_document->findPart(m_partId);
const SkeletonPart *part = m_document->findPart(m_partId);
if (!part) {
qDebug() << "Part not found:" << m_partId;
return;
@ -183,7 +183,7 @@ PartWidget::PartWidget(const Document *document, QUuid partId) :
});
connect(m_xMirrorButton, &QPushButton::clicked, [=]() {
const Part *part = m_document->findPart(m_partId);
const SkeletonPart *part = m_document->findPart(m_partId);
if (!part) {
qDebug() << "Part not found:" << m_partId;
return;
@ -193,7 +193,7 @@ PartWidget::PartWidget(const Document *document, QUuid partId) :
});
connect(m_deformButton, &QPushButton::clicked, [=]() {
const Part *part = m_document->findPart(m_partId);
const SkeletonPart *part = m_document->findPart(m_partId);
if (!part) {
qDebug() << "Part not found:" << m_partId;
return;
@ -202,7 +202,7 @@ PartWidget::PartWidget(const Document *document, QUuid partId) :
});
connect(m_roundButton, &QPushButton::clicked, [=]() {
const Part *part = m_document->findPart(m_partId);
const SkeletonPart *part = m_document->findPart(m_partId);
if (!part) {
qDebug() << "Part not found:" << m_partId;
return;
@ -212,7 +212,7 @@ PartWidget::PartWidget(const Document *document, QUuid partId) :
});
connect(m_colorButton, &QPushButton::clicked, [=]() {
const Part *part = m_document->findPart(m_partId);
const SkeletonPart *part = m_document->findPart(m_partId);
if (!part) {
qDebug() << "Part not found:" << m_partId;
return;
@ -221,7 +221,7 @@ PartWidget::PartWidget(const Document *document, QUuid partId) :
});
connect(m_wrapButton, &QPushButton::clicked, [=]() {
const Part *part = m_document->findPart(m_partId);
const SkeletonPart *part = m_document->findPart(m_partId);
if (!part) {
qDebug() << "Part not found:" << m_partId;
return;
@ -287,7 +287,7 @@ void PartWidget::showColorSettingPopup(const QPoint &pos)
{
QMenu popupMenu;
const Part *part = m_document->findPart(m_partId);
const SkeletonPart *part = m_document->findPart(m_partId);
if (!part) {
qDebug() << "Find part failed:" << m_partId;
return;
@ -358,7 +358,7 @@ void PartWidget::showDeformSettingPopup(const QPoint &pos)
{
QMenu popupMenu;
const Part *part = m_document->findPart(m_partId);
const SkeletonPart *part = m_document->findPart(m_partId);
if (!part) {
qDebug() << "Find part failed:" << m_partId;
return;
@ -434,7 +434,7 @@ void PartWidget::updateButton(QPushButton *button, QChar icon, bool highlighted)
void PartWidget::updatePreview()
{
const Part *part = m_document->findPart(m_partId);
const SkeletonPart *part = m_document->findPart(m_partId);
if (!part) {
qDebug() << "Part not found:" << m_partId;
return;
@ -446,7 +446,7 @@ void PartWidget::updatePreview()
void PartWidget::updateLockButton()
{
const Part *part = m_document->findPart(m_partId);
const SkeletonPart *part = m_document->findPart(m_partId);
if (!part) {
qDebug() << "Part not found:" << m_partId;
return;
@ -459,7 +459,7 @@ void PartWidget::updateLockButton()
void PartWidget::updateVisibleButton()
{
const Part *part = m_document->findPart(m_partId);
const SkeletonPart *part = m_document->findPart(m_partId);
if (!part) {
qDebug() << "Part not found:" << m_partId;
return;
@ -472,7 +472,7 @@ void PartWidget::updateVisibleButton()
void PartWidget::updateSubdivButton()
{
const Part *part = m_document->findPart(m_partId);
const SkeletonPart *part = m_document->findPart(m_partId);
if (!part) {
qDebug() << "Part not found:" << m_partId;
return;
@ -485,7 +485,7 @@ void PartWidget::updateSubdivButton()
void PartWidget::updateDisableButton()
{
const Part *part = m_document->findPart(m_partId);
const SkeletonPart *part = m_document->findPart(m_partId);
if (!part) {
qDebug() << "Part not found:" << m_partId;
return;
@ -498,7 +498,7 @@ void PartWidget::updateDisableButton()
void PartWidget::updateXmirrorButton()
{
const Part *part = m_document->findPart(m_partId);
const SkeletonPart *part = m_document->findPart(m_partId);
if (!part) {
qDebug() << "Part not found:" << m_partId;
return;
@ -511,7 +511,7 @@ void PartWidget::updateXmirrorButton()
void PartWidget::updateDeformButton()
{
const Part *part = m_document->findPart(m_partId);
const SkeletonPart *part = m_document->findPart(m_partId);
if (!part) {
qDebug() << "Part not found:" << m_partId;
return;
@ -524,7 +524,7 @@ void PartWidget::updateDeformButton()
void PartWidget::updateRoundButton()
{
const Part *part = m_document->findPart(m_partId);
const SkeletonPart *part = m_document->findPart(m_partId);
if (!part) {
qDebug() << "Part not found:" << m_partId;
return;
@ -537,7 +537,7 @@ void PartWidget::updateRoundButton()
void PartWidget::updateColorButton()
{
const Part *part = m_document->findPart(m_partId);
const SkeletonPart *part = m_document->findPart(m_partId);
if (!part) {
qDebug() << "Part not found:" << m_partId;
return;
@ -550,7 +550,7 @@ void PartWidget::updateColorButton()
void PartWidget::updateWrapButton()
{
const Part *part = m_document->findPart(m_partId);
const SkeletonPart *part = m_document->findPart(m_partId);
if (!part) {
qDebug() << "Part not found:" << m_partId;
return;

2
src/skeletondocument.cpp Normal file
View File

@ -0,0 +1,2 @@
#include "skeletondocument.h"

223
src/skeletondocument.h Normal file
View File

@ -0,0 +1,223 @@
#ifndef DUST3D_SKELETON_DOCUMENT_H
#define DUST3D_SKELETON_DOCUMENT_H
#include <QUuid>
#include <QObject>
#include <QString>
#include <cmath>
#include <QImage>
#include "bonemark.h"
#include "theme.h"
#include "meshloader.h"
class SkeletonNode
{
public:
SkeletonNode(const QUuid &withId=QUuid()) :
x(0),
y(0),
z(0),
radius(0),
boneMark(BoneMark::None)
{
id = withId.isNull() ? QUuid::createUuid() : withId;
}
void setRadius(float toRadius)
{
if (toRadius < 0)
toRadius = 0.005;
else if (toRadius > 1)
toRadius = 1;
radius = toRadius;
}
QUuid id;
QUuid partId;
QString name;
float x;
float y;
float z;
float radius;
BoneMark boneMark;
std::vector<QUuid> edgeIds;
};
class SkeletonEdge
{
public:
SkeletonEdge(const QUuid &withId=QUuid())
{
id = withId.isNull() ? QUuid::createUuid() : withId;
}
QUuid id;
QUuid partId;
QString name;
std::vector<QUuid> nodeIds;
QUuid neighborOf(QUuid nodeId) const
{
if (nodeIds.size() != 2)
return QUuid();
return nodeIds[0] == nodeId ? nodeIds[1] : nodeIds[0];
}
};
class SkeletonPart
{
public:
~SkeletonPart()
{
delete m_previewMesh;
}
QUuid id;
QString name;
bool visible;
bool locked;
bool subdived;
bool disabled;
bool xMirrored;
bool zMirrored;
float deformThickness;
float deformWidth;
bool rounded;
QColor color;
bool hasColor;
QUuid componentId;
std::vector<QUuid> nodeIds;
bool dirty;
bool wrapped;
QUuid materialId;
SkeletonPart(const QUuid &withId=QUuid()) :
visible(true),
locked(false),
subdived(false),
disabled(false),
xMirrored(false),
zMirrored(false),
deformThickness(1.0),
deformWidth(1.0),
rounded(false),
color(Theme::white),
hasColor(false),
dirty(true),
wrapped(false)
{
id = withId.isNull() ? QUuid::createUuid() : withId;
}
void setDeformThickness(float toThickness)
{
if (toThickness < 0)
toThickness = 0;
else if (toThickness > 2)
toThickness = 2;
deformThickness = toThickness;
}
void setDeformWidth(float toWidth)
{
if (toWidth < 0)
toWidth = 0;
else if (toWidth > 2)
toWidth = 2;
deformWidth = toWidth;
}
bool deformThicknessAdjusted() const
{
return fabs(deformThickness - 1.0) >= 0.01;
}
bool deformWidthAdjusted() const
{
return fabs(deformWidth - 1.0) >= 0.01;
}
bool deformAdjusted() const
{
return deformThicknessAdjusted() || deformWidthAdjusted();
}
bool materialAdjusted() const
{
return !materialId.isNull();
}
bool isEditVisible() const
{
return visible && !disabled;
}
void copyAttributes(const SkeletonPart &other)
{
visible = other.visible;
locked = other.locked;
subdived = other.subdived;
disabled = other.disabled;
xMirrored = other.xMirrored;
zMirrored = other.zMirrored;
deformThickness = other.deformThickness;
deformWidth = other.deformWidth;
rounded = other.rounded;
color = other.color;
hasColor = other.hasColor;
wrapped = other.wrapped;
componentId = other.componentId;
dirty = other.dirty;
materialId = other.materialId;
}
void updatePreviewMesh(MeshLoader *previewMesh)
{
delete m_previewMesh;
m_previewMesh = previewMesh;
}
MeshLoader *takePreviewMesh() const
{
if (nullptr == m_previewMesh)
return nullptr;
return new MeshLoader(*m_previewMesh);
}
private:
Q_DISABLE_COPY(SkeletonPart);
MeshLoader *m_previewMesh = nullptr;
};
enum class SkeletonDocumentEditMode
{
Add = 0,
Select,
Drag,
ZoomIn,
ZoomOut
};
enum class SkeletonProfile
{
Unknown = 0,
Main,
Side
};
class SkeletonDocument : public QObject
{
Q_OBJECT
public:
float originX = 0;
float originY = 0;
float originZ = 0;
SkeletonDocumentEditMode editMode = SkeletonDocumentEditMode::Select;
bool xlocked = false;
bool ylocked = false;
bool zlocked = false;
bool radiusLocked = false;
QImage turnaround;
virtual const SkeletonNode *findNode(QUuid nodeId) const = 0;
virtual const SkeletonEdge *findEdge(QUuid edgeId) const = 0;
virtual const SkeletonPart *findPart(QUuid partId) const = 0;
virtual const SkeletonEdge *findEdgeByNodes(QUuid firstNodeId, QUuid secondNodeId) const = 0;
virtual bool undoable() const = 0;
virtual bool redoable() const = 0;
virtual bool hasPastableNodesInClipboard() const = 0;
virtual bool originSettled() const = 0;
virtual bool isNodeEditable(QUuid nodeId) const = 0;
virtual bool isEdgeEditable(QUuid edgeId) const = 0;
virtual void findAllNeighbors(QUuid nodeId, std::set<QUuid> &neighbors) const = 0;
virtual void copyNodes(std::set<QUuid> nodeIdSet) const = 0;
public slots:
virtual void undo() = 0;
virtual void redo() = 0;
virtual void paste() = 0;
};
#endif

View File

@ -7,7 +7,6 @@
#include <QVector2D>
#include <QMenu>
#include <QApplication>
#include <QClipboard>
#include <QMatrix4x4>
#include "skeletongraphicswidget.h"
#include "theme.h"
@ -15,7 +14,7 @@
#include "snapshotxml.h"
#include "markiconcreator.h"
SkeletonGraphicsWidget::SkeletonGraphicsWidget(const Document *document) :
SkeletonGraphicsWidget::SkeletonGraphicsWidget(const SkeletonDocument *document) :
m_document(document),
m_backgroundItem(nullptr),
m_turnaroundChanged(false),
@ -45,7 +44,7 @@ SkeletonGraphicsWidget::SkeletonGraphicsWidget(const Document *document) :
m_eventForwardingToModelWidget(false),
m_modelWidget(nullptr),
m_inTempDragMode(false),
m_modeBeforeEnterTempDragMode(DocumentEditMode::Select)
m_modeBeforeEnterTempDragMode(SkeletonDocumentEditMode::Select)
{
setRenderHint(QPainter::Antialiasing, false);
setBackgroundBrush(QBrush(QWidget::palette().color(QWidget::backgroundRole()), Qt::SolidPattern));
@ -107,12 +106,12 @@ void SkeletonGraphicsWidget::disableBackgroundBlur()
void SkeletonGraphicsWidget::showContextMenu(const QPoint &pos)
{
if (DocumentEditMode::Add == m_document->editMode) {
emit setEditMode(DocumentEditMode::Select);
if (SkeletonDocumentEditMode::Add == m_document->editMode) {
emit setEditMode(SkeletonDocumentEditMode::Select);
return;
}
if (DocumentEditMode::Select != m_document->editMode) {
if (SkeletonDocumentEditMode::Select != m_document->editMode) {
return;
}
@ -120,19 +119,19 @@ void SkeletonGraphicsWidget::showContextMenu(const QPoint &pos)
QAction addAction(tr("Add..."), this);
connect(&addAction, &QAction::triggered, [=]() {
emit setEditMode(DocumentEditMode::Add);
emit setEditMode(SkeletonDocumentEditMode::Add);
});
contextMenu.addAction(&addAction);
QAction undoAction(tr("Undo"), this);
if (m_document->undoable()) {
connect(&undoAction, &QAction::triggered, m_document, &Document::undo);
connect(&undoAction, &QAction::triggered, m_document, &SkeletonDocument::undo);
contextMenu.addAction(&undoAction);
}
QAction redoAction(tr("Redo"), this);
if (m_document->redoable()) {
connect(&redoAction, &QAction::triggered, m_document, &Document::redo);
connect(&redoAction, &QAction::triggered, m_document, &SkeletonDocument::redo);
contextMenu.addAction(&redoAction);
}
@ -168,7 +167,7 @@ void SkeletonGraphicsWidget::showContextMenu(const QPoint &pos)
QAction pasteAction(tr("Paste"), this);
if (m_document->hasPastableNodesInClipboard()) {
connect(&pasteAction, &QAction::triggered, m_document, &Document::paste);
connect(&pasteAction, &QAction::triggered, m_document, &SkeletonDocument::paste);
contextMenu.addAction(&pasteAction);
}
@ -404,7 +403,7 @@ void SkeletonGraphicsWidget::alignSelectedToGlobal(bool alignToVerticalCenter, b
return;
emit batchChangeBegin();
for (const auto &nodeItem: nodeItems) {
const Node *node = m_document->findNode(nodeItem->id());
const SkeletonNode *node = m_document->findNode(nodeItem->id());
if (!node) {
qDebug() << "Find node id failed:" << nodeItem->id();
continue;
@ -530,25 +529,25 @@ void SkeletonGraphicsWidget::turnaroundImageReady()
void SkeletonGraphicsWidget::updateCursor()
{
if (DocumentEditMode::Add != m_document->editMode) {
if (SkeletonDocumentEditMode::Add != m_document->editMode) {
m_cursorEdgeItem->hide();
m_cursorNodeItem->hide();
}
switch (m_document->editMode) {
case DocumentEditMode::Add:
case SkeletonDocumentEditMode::Add:
setCursor(QCursor(Theme::awesome()->icon(fa::plus).pixmap(Theme::toolIconFontSize, Theme::toolIconFontSize)));
break;
case DocumentEditMode::Select:
case SkeletonDocumentEditMode::Select:
setCursor(QCursor(Theme::awesome()->icon(fa::mousepointer).pixmap(Theme::toolIconFontSize, Theme::toolIconFontSize), Theme::toolIconFontSize / 5, 0));
break;
case DocumentEditMode::Drag:
case SkeletonDocumentEditMode::Drag:
setCursor(QCursor(Theme::awesome()->icon(m_dragStarted ? fa::handrocko : fa::handpapero).pixmap(Theme::toolIconFontSize, Theme::toolIconFontSize)));
break;
case DocumentEditMode::ZoomIn:
case SkeletonDocumentEditMode::ZoomIn:
setCursor(QCursor(Theme::awesome()->icon(fa::searchplus).pixmap(Theme::toolIconFontSize, Theme::toolIconFontSize)));
break;
case DocumentEditMode::ZoomOut:
case SkeletonDocumentEditMode::ZoomOut:
setCursor(QCursor(Theme::awesome()->icon(fa::searchminus).pixmap(Theme::toolIconFontSize, Theme::toolIconFontSize)));
break;
}
@ -559,7 +558,7 @@ void SkeletonGraphicsWidget::updateCursor()
void SkeletonGraphicsWidget::editModeChanged()
{
updateCursor();
if (DocumentEditMode::Add == m_document->editMode) {
if (SkeletonDocumentEditMode::Add == m_document->editMode) {
SkeletonGraphicsNodeItem *choosenNodeItem = nullptr;
if (!m_rangeSelectionSet.empty()) {
std::set<SkeletonGraphicsNodeItem *> nodeItems;
@ -648,7 +647,7 @@ bool SkeletonGraphicsWidget::mouseMove(QMouseEvent *event)
return true;
}
if (DocumentEditMode::Select == m_document->editMode) {
if (SkeletonDocumentEditMode::Select == m_document->editMode) {
if (m_rangeSelectionStarted) {
QPointF mouseScenePos = mouseEventScenePos(event);
m_selectionItem->updateRange(m_rangeSelectionStartPos, mouseScenePos);
@ -659,8 +658,8 @@ bool SkeletonGraphicsWidget::mouseMove(QMouseEvent *event)
}
}
if (DocumentEditMode::Select == m_document->editMode ||
DocumentEditMode::Add == m_document->editMode) {
if (SkeletonDocumentEditMode::Select == m_document->editMode ||
SkeletonDocumentEditMode::Add == m_document->editMode) {
//
// > For overlapping nodes, you can make it a bit better by selecting the node center nearest the mouse, rather than simply checking against the wider circle.
@ -746,7 +745,7 @@ bool SkeletonGraphicsWidget::mouseMove(QMouseEvent *event)
hoverPart(hoveredPartId);
}
if (DocumentEditMode::Add == m_document->editMode) {
if (SkeletonDocumentEditMode::Add == m_document->editMode) {
QPointF mouseScenePos = mouseEventScenePos(event);
m_cursorNodeItem->setOrigin(mouseScenePos);
if (!m_cursorNodeItem->isVisible()) {
@ -761,7 +760,7 @@ bool SkeletonGraphicsWidget::mouseMove(QMouseEvent *event)
return true;
}
if (DocumentEditMode::Select == m_document->editMode) {
if (SkeletonDocumentEditMode::Select == m_document->editMode) {
if (m_moveStarted) {
if (m_checkedOriginItem) {
QPointF mouseScenePos = mouseEventScenePos(event);
@ -781,7 +780,7 @@ bool SkeletonGraphicsWidget::mouseMove(QMouseEvent *event)
bool ikMoved = false;
if (nodeItems.size() == 1) {
auto &nodeItem = *nodeItems.begin();
const Node *node = m_document->findNode(nodeItem->id());
const SkeletonNode *node = m_document->findNode(nodeItem->id());
if (node->edgeIds.size() == 1) {
const auto origin = nodeItem->origin();
byX = mouseScenePos.x() - origin.x();
@ -1024,12 +1023,12 @@ bool SkeletonGraphicsWidget::wheel(QWheelEvent *event)
if (fabs(delta) < 1)
delta = delta < 0 ? -1.0 : 1.0;
}
if (DocumentEditMode::Add == m_document->editMode) {
if (SkeletonDocumentEditMode::Add == m_document->editMode) {
if (m_cursorNodeItem->isVisible()) {
m_cursorNodeItem->setRadius(m_cursorNodeItem->radius() + delta);
return true;
}
} else if (DocumentEditMode::Select == m_document->editMode) {
} else if (SkeletonDocumentEditMode::Select == m_document->editMode) {
if (!m_rangeSelectionSet.empty()) {
if (QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ControlModifier)) {
scaleSelected(delta);
@ -1165,13 +1164,13 @@ QPointF SkeletonGraphicsWidget::mouseEventScenePos(QMouseEvent *event)
bool SkeletonGraphicsWidget::mousePress(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
if (DocumentEditMode::ZoomIn == m_document->editMode) {
if (SkeletonDocumentEditMode::ZoomIn == m_document->editMode) {
ViewportAnchor lastAnchor = transformationAnchor();
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
scale(1.5, 1.5);
setTransformationAnchor(lastAnchor);
return true;
} else if (DocumentEditMode::ZoomOut == m_document->editMode) {
} else if (SkeletonDocumentEditMode::ZoomOut == m_document->editMode) {
ViewportAnchor lastAnchor = transformationAnchor();
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
scale(0.5, 0.5);
@ -1181,13 +1180,13 @@ bool SkeletonGraphicsWidget::mousePress(QMouseEvent *event)
setTransform(QTransform());
}
return true;
} else if (DocumentEditMode::Drag == m_document->editMode) {
} else if (SkeletonDocumentEditMode::Drag == m_document->editMode) {
if (!m_dragStarted) {
m_lastGlobalPos = event->globalPos();
m_dragStarted = true;
updateCursor();
}
} else if (DocumentEditMode::Add == m_document->editMode) {
} else if (SkeletonDocumentEditMode::Add == m_document->editMode) {
if (m_cursorNodeItem->isVisible()) {
if (m_addFromNodeItem) {
if (m_hoveredNodeItem && m_addFromNodeItem &&
@ -1226,7 +1225,7 @@ bool SkeletonGraphicsWidget::mousePress(QMouseEvent *event)
emit groupOperationAdded();
return true;
}
} else if (DocumentEditMode::Select == m_document->editMode) {
} else if (SkeletonDocumentEditMode::Select == m_document->editMode) {
bool processed = false;
if (m_hoveredOriginItem != m_checkedOriginItem) {
if (m_checkedOriginItem) {
@ -1284,7 +1283,7 @@ bool SkeletonGraphicsWidget::mousePress(QMouseEvent *event)
}
if (event->button() == Qt::LeftButton) {
if (DocumentEditMode::Select == m_document->editMode) {
if (SkeletonDocumentEditMode::Select == m_document->editMode) {
if (!m_rangeSelectionStarted) {
m_rangeSelectionStartPos = mouseEventScenePos(event);
m_rangeSelectionStarted = true;
@ -1398,10 +1397,10 @@ void SkeletonGraphicsWidget::shortcutDelete()
void SkeletonGraphicsWidget::shortcutAddMode()
{
if (DocumentEditMode::Add == m_document->editMode) {
emit setEditMode(DocumentEditMode::Select);
if (SkeletonDocumentEditMode::Add == m_document->editMode) {
emit setEditMode(SkeletonDocumentEditMode::Select);
} else {
emit setEditMode(DocumentEditMode::Add);
emit setEditMode(SkeletonDocumentEditMode::Add);
}
}
@ -1452,12 +1451,12 @@ void SkeletonGraphicsWidget::shortcutSave()
void SkeletonGraphicsWidget::shortcutSelectMode()
{
emit setEditMode(DocumentEditMode::Select);
emit setEditMode(SkeletonDocumentEditMode::Select);
}
void SkeletonGraphicsWidget::shortcutDragMode()
{
emit setEditMode(DocumentEditMode::Drag);
emit setEditMode(SkeletonDocumentEditMode::Drag);
}
void SkeletonGraphicsWidget::shortcutZoomRenderedModelByMinus10()
@ -1467,7 +1466,7 @@ void SkeletonGraphicsWidget::shortcutZoomRenderedModelByMinus10()
void SkeletonGraphicsWidget::shortcutZoomSelectedByMinus1()
{
if (DocumentEditMode::Select == m_document->editMode && hasSelection()) {
if (SkeletonDocumentEditMode::Select == m_document->editMode && hasSelection()) {
zoomSelected(-1);
emit groupOperationAdded();
}
@ -1480,7 +1479,7 @@ void SkeletonGraphicsWidget::shortcutZoomRenderedModelBy10()
void SkeletonGraphicsWidget::shortcutZoomSelectedBy1()
{
if (DocumentEditMode::Select == m_document->editMode && hasSelection()) {
if (SkeletonDocumentEditMode::Select == m_document->editMode && hasSelection()) {
zoomSelected(1);
emit groupOperationAdded();
}
@ -1488,7 +1487,7 @@ void SkeletonGraphicsWidget::shortcutZoomSelectedBy1()
void SkeletonGraphicsWidget::shortcutRotateSelectedByMinus1()
{
if (DocumentEditMode::Select == m_document->editMode && hasSelection()) {
if (SkeletonDocumentEditMode::Select == m_document->editMode && hasSelection()) {
rotateSelected(-1);
emit groupOperationAdded();
}
@ -1496,7 +1495,7 @@ void SkeletonGraphicsWidget::shortcutRotateSelectedByMinus1()
void SkeletonGraphicsWidget::shortcutRotateSelectedBy1()
{
if (DocumentEditMode::Select == m_document->editMode && hasSelection()) {
if (SkeletonDocumentEditMode::Select == m_document->editMode && hasSelection()) {
rotateSelected(1);
emit groupOperationAdded();
}
@ -1504,7 +1503,7 @@ void SkeletonGraphicsWidget::shortcutRotateSelectedBy1()
void SkeletonGraphicsWidget::shortcutMoveSelectedToLeft()
{
if (DocumentEditMode::Select == m_document->editMode) {
if (SkeletonDocumentEditMode::Select == m_document->editMode) {
if (m_checkedOriginItem) {
moveCheckedOrigin(-1, 0);
emit groupOperationAdded();
@ -1517,7 +1516,7 @@ void SkeletonGraphicsWidget::shortcutMoveSelectedToLeft()
void SkeletonGraphicsWidget::shortcutMoveSelectedToRight()
{
if (DocumentEditMode::Select == m_document->editMode) {
if (SkeletonDocumentEditMode::Select == m_document->editMode) {
if (m_checkedOriginItem) {
moveCheckedOrigin(1, 0);
emit groupOperationAdded();
@ -1530,7 +1529,7 @@ void SkeletonGraphicsWidget::shortcutMoveSelectedToRight()
void SkeletonGraphicsWidget::shortcutMoveSelectedToUp()
{
if (DocumentEditMode::Select == m_document->editMode) {
if (SkeletonDocumentEditMode::Select == m_document->editMode) {
if (m_checkedOriginItem) {
moveCheckedOrigin(0, -1);
emit groupOperationAdded();
@ -1543,7 +1542,7 @@ void SkeletonGraphicsWidget::shortcutMoveSelectedToUp()
void SkeletonGraphicsWidget::shortcutMoveSelectedToDown()
{
if (DocumentEditMode::Select == m_document->editMode) {
if (SkeletonDocumentEditMode::Select == m_document->editMode) {
if (m_checkedOriginItem) {
moveCheckedOrigin(0, 1);
emit groupOperationAdded();
@ -1556,7 +1555,7 @@ void SkeletonGraphicsWidget::shortcutMoveSelectedToDown()
void SkeletonGraphicsWidget::shortcutScaleSelectedByMinus1()
{
if (DocumentEditMode::Select == m_document->editMode && hasSelection()) {
if (SkeletonDocumentEditMode::Select == m_document->editMode && hasSelection()) {
scaleSelected(-1);
emit groupOperationAdded();
}
@ -1564,7 +1563,7 @@ void SkeletonGraphicsWidget::shortcutScaleSelectedByMinus1()
void SkeletonGraphicsWidget::shortcutScaleSelectedBy1()
{
if (DocumentEditMode::Select == m_document->editMode && hasSelection()) {
if (SkeletonDocumentEditMode::Select == m_document->editMode && hasSelection()) {
scaleSelected(1);
emit groupOperationAdded();
}
@ -1572,15 +1571,15 @@ void SkeletonGraphicsWidget::shortcutScaleSelectedBy1()
void SkeletonGraphicsWidget::shortcutSwitchProfileOnSelected()
{
if (DocumentEditMode::Select == m_document->editMode && hasSelection()) {
if (SkeletonDocumentEditMode::Select == m_document->editMode && hasSelection()) {
switchProfileOnRangeSelection();
}
}
void SkeletonGraphicsWidget::shortcutShowOrHideSelectedPart()
{
if (DocumentEditMode::Select == m_document->editMode && !m_lastCheckedPart.isNull()) {
const Part *part = m_document->findPart(m_lastCheckedPart);
if (SkeletonDocumentEditMode::Select == m_document->editMode && !m_lastCheckedPart.isNull()) {
const SkeletonPart *part = m_document->findPart(m_lastCheckedPart);
bool partVisible = part && part->visible;
emit setPartVisibleState(m_lastCheckedPart, !partVisible);
emit groupOperationAdded();
@ -1589,8 +1588,8 @@ void SkeletonGraphicsWidget::shortcutShowOrHideSelectedPart()
void SkeletonGraphicsWidget::shortcutEnableOrDisableSelectedPart()
{
if (DocumentEditMode::Select == m_document->editMode && !m_lastCheckedPart.isNull()) {
const Part *part = m_document->findPart(m_lastCheckedPart);
if (SkeletonDocumentEditMode::Select == m_document->editMode && !m_lastCheckedPart.isNull()) {
const SkeletonPart *part = m_document->findPart(m_lastCheckedPart);
bool partDisabled = part && part->disabled;
emit setPartDisableState(m_lastCheckedPart, !partDisabled);
emit groupOperationAdded();
@ -1599,8 +1598,8 @@ void SkeletonGraphicsWidget::shortcutEnableOrDisableSelectedPart()
void SkeletonGraphicsWidget::shortcutLockOrUnlockSelectedPart()
{
if (DocumentEditMode::Select == m_document->editMode && !m_lastCheckedPart.isNull()) {
const Part *part = m_document->findPart(m_lastCheckedPart);
if (SkeletonDocumentEditMode::Select == m_document->editMode && !m_lastCheckedPart.isNull()) {
const SkeletonPart *part = m_document->findPart(m_lastCheckedPart);
bool partLocked = part && part->locked;
emit setPartLockState(m_lastCheckedPart, !partLocked);
emit groupOperationAdded();
@ -1609,8 +1608,8 @@ void SkeletonGraphicsWidget::shortcutLockOrUnlockSelectedPart()
void SkeletonGraphicsWidget::shortcutXmirrorOnOrOffSelectedPart()
{
if (DocumentEditMode::Select == m_document->editMode && !m_lastCheckedPart.isNull()) {
const Part *part = m_document->findPart(m_lastCheckedPart);
if (SkeletonDocumentEditMode::Select == m_document->editMode && !m_lastCheckedPart.isNull()) {
const SkeletonPart *part = m_document->findPart(m_lastCheckedPart);
bool partXmirrored = part && part->xMirrored;
emit setPartXmirrorState(m_lastCheckedPart, !partXmirrored);
emit groupOperationAdded();
@ -1619,8 +1618,8 @@ void SkeletonGraphicsWidget::shortcutXmirrorOnOrOffSelectedPart()
void SkeletonGraphicsWidget::shortcutSubdivedOrNotSelectedPart()
{
if (DocumentEditMode::Select == m_document->editMode && !m_lastCheckedPart.isNull()) {
const Part *part = m_document->findPart(m_lastCheckedPart);
if (SkeletonDocumentEditMode::Select == m_document->editMode && !m_lastCheckedPart.isNull()) {
const SkeletonPart *part = m_document->findPart(m_lastCheckedPart);
bool partSubdived = part && part->subdived;
emit setPartSubdivState(m_lastCheckedPart, !partSubdived);
emit groupOperationAdded();
@ -1629,8 +1628,8 @@ void SkeletonGraphicsWidget::shortcutSubdivedOrNotSelectedPart()
void SkeletonGraphicsWidget::shortcutRoundEndOrNotSelectedPart()
{
if (DocumentEditMode::Select == m_document->editMode && !m_lastCheckedPart.isNull()) {
const Part *part = m_document->findPart(m_lastCheckedPart);
if (SkeletonDocumentEditMode::Select == m_document->editMode && !m_lastCheckedPart.isNull()) {
const SkeletonPart *part = m_document->findPart(m_lastCheckedPart);
bool partRounded = part && part->rounded;
emit setPartRoundState(m_lastCheckedPart, !partRounded);
emit groupOperationAdded();
@ -1639,8 +1638,8 @@ void SkeletonGraphicsWidget::shortcutRoundEndOrNotSelectedPart()
void SkeletonGraphicsWidget::shortcutWrapOrNotSelectedPart()
{
if (DocumentEditMode::Select == m_document->editMode && !m_lastCheckedPart.isNull()) {
const Part *part = m_document->findPart(m_lastCheckedPart);
if (SkeletonDocumentEditMode::Select == m_document->editMode && !m_lastCheckedPart.isNull()) {
const SkeletonPart *part = m_document->findPart(m_lastCheckedPart);
bool partWrapped = part && part->wrapped;
emit setPartWrapState(m_lastCheckedPart, !partWrapped);
emit groupOperationAdded();
@ -1650,13 +1649,13 @@ void SkeletonGraphicsWidget::shortcutWrapOrNotSelectedPart()
bool SkeletonGraphicsWidget::keyPress(QKeyEvent *event)
{
if (event->key() == Qt::Key_Space) {
if (DocumentEditMode::ZoomIn == m_document->editMode ||
DocumentEditMode::ZoomOut == m_document->editMode ||
DocumentEditMode::Select == m_document->editMode ||
DocumentEditMode::Add == m_document->editMode) {
if (SkeletonDocumentEditMode::ZoomIn == m_document->editMode ||
SkeletonDocumentEditMode::ZoomOut == m_document->editMode ||
SkeletonDocumentEditMode::Select == m_document->editMode ||
SkeletonDocumentEditMode::Add == m_document->editMode) {
m_inTempDragMode = true;
m_modeBeforeEnterTempDragMode = m_document->editMode;
emit setEditMode(DocumentEditMode::Drag);
emit setEditMode(SkeletonDocumentEditMode::Drag);
return true;
}
}
@ -1692,7 +1691,7 @@ void SkeletonGraphicsWidget::originChanged()
void SkeletonGraphicsWidget::nodeAdded(QUuid nodeId)
{
const Node *node = m_document->findNode(nodeId);
const SkeletonNode *node = m_document->findNode(nodeId);
if (nullptr == node) {
qDebug() << "New node added but node id not exist:" << nodeId;
return;
@ -1730,7 +1729,7 @@ void SkeletonGraphicsWidget::nodeAdded(QUuid nodeId)
void SkeletonGraphicsWidget::edgeAdded(QUuid edgeId)
{
const Edge *edge = m_document->findEdge(edgeId);
const SkeletonEdge *edge = m_document->findEdge(edgeId);
if (nullptr == edge) {
qDebug() << "New edge added but edge id not exist:" << edgeId;
return;
@ -1810,7 +1809,7 @@ void SkeletonGraphicsWidget::edgeRemoved(QUuid edgeId)
void SkeletonGraphicsWidget::nodeRadiusChanged(QUuid nodeId)
{
const Node *node = m_document->findNode(nodeId);
const SkeletonNode *node = m_document->findNode(nodeId);
if (nullptr == node) {
qDebug() << "Node changed but node id not exist:" << nodeId;
return;
@ -1827,7 +1826,7 @@ void SkeletonGraphicsWidget::nodeRadiusChanged(QUuid nodeId)
void SkeletonGraphicsWidget::nodeBoneMarkChanged(QUuid nodeId)
{
const Node *node = m_document->findNode(nodeId);
const SkeletonNode *node = m_document->findNode(nodeId);
if (nullptr == node) {
qDebug() << "Node changed but node id not exist:" << nodeId;
return;
@ -1844,7 +1843,7 @@ void SkeletonGraphicsWidget::nodeBoneMarkChanged(QUuid nodeId)
void SkeletonGraphicsWidget::nodeOriginChanged(QUuid nodeId)
{
const Node *node = m_document->findNode(nodeId);
const SkeletonNode *node = m_document->findNode(nodeId);
if (nullptr == node) {
qDebug() << "Node changed but node id not exist:" << nodeId;
return;
@ -1875,9 +1874,9 @@ void SkeletonGraphicsWidget::edgeChanged(QUuid edgeId)
void SkeletonGraphicsWidget::partVisibleStateChanged(QUuid partId)
{
const Part *part = m_document->findPart(partId);
const SkeletonPart *part = m_document->findPart(partId);
for (const auto &nodeId: part->nodeIds) {
const Node *node = m_document->findNode(nodeId);
const SkeletonNode *node = m_document->findNode(nodeId);
for (auto edgeIt = node->edgeIds.begin(); edgeIt != node->edgeIds.end(); edgeIt++) {
auto edgeItemIt = edgeItemMap.find(*edgeIt);
if (edgeItemIt == edgeItemMap.end()) {
@ -1931,7 +1930,7 @@ QUuid SkeletonGraphicsWidget::querySkeletonItemPartId(QGraphicsItem *item)
{
if (item->data(0) == "node") {
SkeletonGraphicsNodeItem *nodeItem = (SkeletonGraphicsNodeItem *)item;
const Node *node = m_document->findNode(nodeItem->id());
const SkeletonNode *node = m_document->findNode(nodeItem->id());
if (!node) {
qDebug() << "Find node id failed:" << nodeItem->id();
return QUuid();
@ -1939,7 +1938,7 @@ QUuid SkeletonGraphicsWidget::querySkeletonItemPartId(QGraphicsItem *item)
return node->partId;
} else if (item->data(0) == "edge") {
SkeletonGraphicsEdgeItem *edgeItem = (SkeletonGraphicsEdgeItem *)item;
const Edge *edge = m_document->findEdge(edgeItem->id());
const SkeletonEdge *edge = m_document->findEdge(edgeItem->id());
if (!edge) {
qDebug() << "Find edge id failed:" << edgeItem->id();
return QUuid();
@ -2081,7 +2080,7 @@ void SkeletonGraphicsWidget::selectPartAllById(QUuid partId)
unselectAll();
for (const auto &it: nodeItemMap) {
SkeletonGraphicsNodeItem *item = it.second.first;
const Node *node = m_document->findNode(item->id());
const SkeletonNode *node = m_document->findNode(item->id());
if (!node)
continue;
if (node->partId != partId)
@ -2090,7 +2089,7 @@ void SkeletonGraphicsWidget::selectPartAllById(QUuid partId)
}
for (const auto &it: edgeItemMap) {
SkeletonGraphicsEdgeItem *item = it.second.first;
const Edge *edge = m_document->findEdge(item->id());
const SkeletonEdge *edge = m_document->findEdge(item->id());
if (!edge)
continue;
if (edge->partId != partId)
@ -2133,7 +2132,7 @@ void SkeletonGraphicsWidget::addPartToSelection(QUuid partId)
QUuid choosenPartId = partId;
for (const auto &it: nodeItemMap) {
SkeletonGraphicsNodeItem *item = SkeletonProfile::Main == choosenProfile ? it.second.first : it.second.second;
const Node *node = m_document->findNode(item->id());
const SkeletonNode *node = m_document->findNode(item->id());
if (!node)
continue;
if (choosenPartId.isNull()) {
@ -2145,7 +2144,7 @@ void SkeletonGraphicsWidget::addPartToSelection(QUuid partId)
}
for (const auto &it: edgeItemMap) {
SkeletonGraphicsEdgeItem *item = SkeletonProfile::Main == choosenProfile ? it.second.first : it.second.second;
const Edge *edge = m_document->findEdge(item->id());
const SkeletonEdge *edge = m_document->findEdge(item->id());
if (!edge)
continue;
if (choosenPartId.isNull()) {
@ -2164,18 +2163,18 @@ void SkeletonGraphicsWidget::selectPartAll()
QUuid choosenPartId;
if (m_hoveredNodeItem) {
choosenProfile = m_hoveredNodeItem->profile();
const Node *node = m_document->findNode(m_hoveredNodeItem->id());
const SkeletonNode *node = m_document->findNode(m_hoveredNodeItem->id());
if (node)
choosenPartId = node->partId;
} else if (m_hoveredEdgeItem) {
choosenProfile = m_hoveredEdgeItem->profile();
const Edge *edge = m_document->findEdge(m_hoveredEdgeItem->id());
const SkeletonEdge *edge = m_document->findEdge(m_hoveredEdgeItem->id());
if (edge)
choosenPartId = edge->partId;
}
for (const auto &it: nodeItemMap) {
SkeletonGraphicsNodeItem *item = SkeletonProfile::Main == choosenProfile ? it.second.first : it.second.second;
const Node *node = m_document->findNode(item->id());
const SkeletonNode *node = m_document->findNode(item->id());
if (!node)
continue;
if (choosenPartId.isNull()) {
@ -2187,7 +2186,7 @@ void SkeletonGraphicsWidget::selectPartAll()
}
for (const auto &it: edgeItemMap) {
SkeletonGraphicsEdgeItem *item = SkeletonProfile::Main == choosenProfile ? it.second.first : it.second.second;
const Edge *edge = m_document->findEdge(item->id());
const SkeletonEdge *edge = m_document->findEdge(item->id());
if (!edge)
continue;
if (choosenPartId.isNull()) {
@ -2253,13 +2252,7 @@ void SkeletonGraphicsWidget::copy()
readSkeletonNodeAndEdgeIdSetFromRangeSelection(&nodeIdSet, &edgeIdSet);
if (nodeIdSet.empty())
return;
Snapshot snapshot;
m_document->toSnapshot(&snapshot, nodeIdSet, DocumentToSnapshotFor::Nodes);
QString snapshotXml;
QXmlStreamWriter xmlStreamWriter(&snapshotXml);
saveSkeletonToXmlStream(&snapshot, &xmlStreamWriter);
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(snapshotXml);
m_document->copyNodes(nodeIdSet);
}
void SkeletonGraphicsWidget::removeAllContent()

View File

@ -12,7 +12,7 @@
#include <cmath>
#include <set>
#include <QTimer>
#include "document.h"
#include "skeletondocument.h"
#include "turnaroundloader.h"
#include "theme.h"
#include "util.h"
@ -350,7 +350,7 @@ signals:
void scaleNodeByAddRadius(QUuid nodeId, float amount);
void moveNodeBy(QUuid nodeId, float x, float y, float z);
void removeNode(QUuid nodeId);
void setEditMode(DocumentEditMode mode);
void setEditMode(SkeletonDocumentEditMode mode);
void removeEdge(QUuid edgeId);
void addEdge(QUuid fromNodeId, QUuid toNodeId);
void cursorChanged();
@ -385,7 +385,7 @@ signals:
void enableAllPositionRelatedLocks();
void disableAllPositionRelatedLocks();
public:
SkeletonGraphicsWidget(const Document *document);
SkeletonGraphicsWidget(const SkeletonDocument *document);
std::map<QUuid, std::pair<SkeletonGraphicsNodeItem *, SkeletonGraphicsNodeItem *>> nodeItemMap;
std::map<QUuid, std::pair<SkeletonGraphicsEdgeItem *, SkeletonGraphicsEdgeItem *>> edgeItemMap;
bool mouseMove(QMouseEvent *event);
@ -527,7 +527,7 @@ private:
void rotateItems(const std::set<SkeletonGraphicsNodeItem *> &nodeItems, int degree, QVector2D center);
void rotateAllSideProfile(int degree);
private: //need initalize
const Document *m_document;
const SkeletonDocument *m_document;
QGraphicsPixmapItem *m_backgroundItem;
bool m_turnaroundChanged;
TurnaroundLoader *m_turnaroundLoader;
@ -556,7 +556,7 @@ private: //need initalize
bool m_eventForwardingToModelWidget;
ModelWidget *m_modelWidget;
bool m_inTempDragMode;
DocumentEditMode m_modeBeforeEnterTempDragMode;
SkeletonDocumentEditMode m_modeBeforeEnterTempDragMode;
private:
QVector3D m_ikMoveTarget;
QUuid m_ikMoveEndEffectorId;