Make a abstract class for document: SkeletonDocument
This is mainly for reusing the SkeletonGraphicsEditWidget for other purpose, such as the new pose editor.master
parent
e7249db089
commit
a4aefdd308
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
227
src/document.h
227
src/document.h
|
@ -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 ¤tPostProcessedOutcome() 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();
|
||||
|
|
|
@ -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, [=]() {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
#include "skeletondocument.h"
|
||||
|
|
@ -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
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue