diff --git a/dust3d.pro b/dust3d.pro index a4ecb247..9642b5c2 100644 --- a/dust3d.pro +++ b/dust3d.pro @@ -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 diff --git a/src/document.cpp b/src/document.cpp index 63c91578..10371f57 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -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 *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 *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 *group, QUuid nodeId void Document::splitPartByNode(std::vector> *groups, QUuid nodeId) { - const Node *node = findNode(nodeId); + const SkeletonNode *node = findNode(nodeId); std::set visitMap; for (auto edgeIt = node->edgeIds.begin(); edgeIt != node->edgeIds.end(); edgeIt++) { std::vector 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> *groups, QUuid no void Document::splitPartByEdge(std::vector> *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 &limitNodeId std::set limitPartIds; std::set 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 nodeIdSet) const +{ + Snapshot snapshot; + toSnapshot(&snapshot, nodeIdSet, DocumentToSnapshotFor::Nodes); + QString snapshotXml; + QXmlStreamWriter xmlStreamWriter(&snapshotXml); + saveSkeletonToXmlStream(&snapshot, &xmlStreamWriter); + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setText(snapshotXml); +} \ No newline at end of file diff --git a/src/document.h b/src/document.h index ce58dd3c..f0614746 100644 --- a/src/document.h +++ b/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 edgeIds; -}; - -class Edge -{ -public: - Edge(const QUuid &withId=QUuid()) - { - id = withId.isNull() ? QUuid::createUuid() : withId; - } - QUuid id; - QUuid partId; - QString name; - std::vector 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 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 partMap; - std::map nodeMap; - std::map edgeMap; + std::map partMap; + std::map nodeMap; + std::map edgeMap; std::map componentMap; std::map materialMap; std::vector materialIdList; @@ -649,8 +464,19 @@ public: std::map motionMap; std::vector 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 &neighbors) const override; + void copyNodes(std::set nodeIdSet) const override; void toSnapshot(Snapshot *snapshot, const std::set &limitNodeIds=std::set(), DocumentToSnapshotFor forWhat=DocumentToSnapshotFor::Document, const std::set &limitPoseIds=std::set(), @@ -658,10 +484,6 @@ public: const std::set &limitMaterialIds=std::set()) 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 *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 &neighbors) const; void collectComponentDescendantParts(QUuid componentId, std::vector &partIds) const; void collectComponentDescendantComponents(QUuid componentId, std::vector &componentIds) const; const std::vector &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(); diff --git a/src/documentwindow.cpp b/src/documentwindow.cpp index ab9799cc..f246e703 100644 --- a/src/documentwindow.cpp +++ b/src/documentwindow.cpp @@ -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, [=]() { diff --git a/src/parttreewidget.cpp b/src/parttreewidget.cpp index 87f7319f..6253f257 100644 --- a/src/parttreewidget.cpp +++ b/src/parttreewidget.cpp @@ -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 unorderedComponentIds = m_selectedComponentIds; diff --git a/src/partwidget.cpp b/src/partwidget.cpp index 048959f8..724239e2 100644 --- a/src/partwidget.cpp +++ b/src/partwidget.cpp @@ -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; diff --git a/src/skeletondocument.cpp b/src/skeletondocument.cpp new file mode 100644 index 00000000..858d0c3e --- /dev/null +++ b/src/skeletondocument.cpp @@ -0,0 +1,2 @@ +#include "skeletondocument.h" + diff --git a/src/skeletondocument.h b/src/skeletondocument.h new file mode 100644 index 00000000..24c5e090 --- /dev/null +++ b/src/skeletondocument.h @@ -0,0 +1,223 @@ +#ifndef DUST3D_SKELETON_DOCUMENT_H +#define DUST3D_SKELETON_DOCUMENT_H +#include +#include +#include +#include +#include +#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 edgeIds; +}; + +class SkeletonEdge +{ +public: + SkeletonEdge(const QUuid &withId=QUuid()) + { + id = withId.isNull() ? QUuid::createUuid() : withId; + } + QUuid id; + QUuid partId; + QString name; + std::vector 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 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 &neighbors) const = 0; + virtual void copyNodes(std::set nodeIdSet) const = 0; + +public slots: + virtual void undo() = 0; + virtual void redo() = 0; + virtual void paste() = 0; +}; + +#endif diff --git a/src/skeletongraphicswidget.cpp b/src/skeletongraphicswidget.cpp index 66d92966..d49ae1ff 100644 --- a/src/skeletongraphicswidget.cpp +++ b/src/skeletongraphicswidget.cpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #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 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() diff --git a/src/skeletongraphicswidget.h b/src/skeletongraphicswidget.h index 21619421..f4db94f6 100644 --- a/src/skeletongraphicswidget.h +++ b/src/skeletongraphicswidget.h @@ -12,7 +12,7 @@ #include #include #include -#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> nodeItemMap; std::map> edgeItemMap; bool mouseMove(QMouseEvent *event); @@ -527,7 +527,7 @@ private: void rotateItems(const std::set &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;