Optimize nodes deletion [skip ci]

If all nodes belong to a part are selected to remove, then the part got
removed, remove part is more light weight than remove nodes and edges
master
huxingyi 2020-04-12 16:18:24 +09:30
parent 7097c22c69
commit a0911a69fd
4 changed files with 60 additions and 2 deletions

View File

@ -3209,6 +3209,7 @@ void Document::paste()
Snapshot snapshot;
loadSkeletonFromXmlStream(&snapshot, xmlStreamReader);
addFromSnapshot(snapshot, SnapshotSource::Paste);
saveSnapshot();
}
}

View File

@ -994,6 +994,7 @@ DocumentWindow::DocumentWindow() :
connect(graphicsWidget, &SkeletonGraphicsWidget::setNodeBoneMark, m_document, &Document::setNodeBoneMark);
connect(graphicsWidget, &SkeletonGraphicsWidget::clearNodeCutFaceSettings, m_document, &Document::clearNodeCutFaceSettings);
connect(graphicsWidget, &SkeletonGraphicsWidget::removeNode, m_document, &Document::removeNode);
connect(graphicsWidget, &SkeletonGraphicsWidget::removePart, m_document, &Document::removePart);
connect(graphicsWidget, &SkeletonGraphicsWidget::setEditMode, m_document, &Document::setEditMode);
connect(graphicsWidget, &SkeletonGraphicsWidget::removeEdge, m_document, &Document::removeEdge);
connect(graphicsWidget, &SkeletonGraphicsWidget::addEdge, m_document, &Document::addEdge);

View File

@ -1732,6 +1732,59 @@ void SkeletonGraphicsWidget::deleteSelected()
std::set<QUuid> nodeIdSet;
std::set<QUuid> edgeIdSet;
readSkeletonNodeAndEdgeIdSetFromRangeSelection(&nodeIdSet, &edgeIdSet);
std::set<QUuid> partIds;
for (const auto &it: nodeIdSet) {
const SkeletonNode *node = m_document->findNode(it);
if (nullptr == node)
continue;
partIds.insert(node->partId);
}
for (const auto &it: edgeIdSet) {
const SkeletonEdge *edge = m_document->findEdge(it);
if (nullptr == edge)
continue;
partIds.insert(edge->partId);
}
std::set<QUuid> cleanupPartIds;
for (const auto &partId: partIds) {
const SkeletonPart *part = m_document->findPart(partId);
if (nullptr != part) {
bool allNodesSelected = true;
for (const auto &it: part->nodeIds) {
if (nodeIdSet.find(it) == nodeIdSet.end()) {
allNodesSelected = false;
break;
}
}
if (allNodesSelected) {
cleanupPartIds.insert(partId);
}
}
}
for (const auto &partId: cleanupPartIds) {
for (auto it = nodeIdSet.begin(); it != nodeIdSet.end(); ) {
const SkeletonNode *node = m_document->findNode(*it);
if (nullptr != node && node->partId == partId) {
it = nodeIdSet.erase(it);
continue;
}
++it;
}
for (auto it = edgeIdSet.begin(); it != edgeIdSet.end(); ) {
const SkeletonEdge *edge = m_document->findEdge(*it);
if (nullptr != edge && edge->partId == partId) {
it = edgeIdSet.erase(it);
continue;
}
++it;
}
}
for (const auto &partId: cleanupPartIds) {
emit removePart(partId);
}
for (const auto &it: nodeIdSet) {
m_deferredRemoveNodeIds.insert(it);
}
@ -1739,9 +1792,11 @@ void SkeletonGraphicsWidget::deleteSelected()
m_deferredRemoveEdgeIds.insert(it);
}
if (!nodeIdSet.empty() || !edgeIdSet.empty()) {
if (nullptr == m_deferredRemoveTimer) {
timeToRemoveDeferredNodesAndEdges();
}
}
}
void SkeletonGraphicsWidget::shortcutDelete()

View File

@ -468,6 +468,7 @@ signals:
void scaleNodeByAddRadius(QUuid nodeId, float amount);
void moveNodeBy(QUuid nodeId, float x, float y, float z);
void removeNode(QUuid nodeId);
void removePart(QUuid partId);
void setEditMode(SkeletonDocumentEditMode mode);
void removeEdge(QUuid edgeId);
void addEdge(QUuid fromNodeId, QUuid toNodeId);