diff --git a/application/sources/document_window.cc b/application/sources/document_window.cc index cabbafa7..2ee665e9 100644 --- a/application/sources/document_window.cc +++ b/application/sources/document_window.cc @@ -540,6 +540,7 @@ DocumentWindow::DocumentWindow() connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::addNode, m_document, &Document::addNode); connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::scaleNodeByAddRadius, m_document, &Document::scaleNodeByAddRadius); connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::moveNodeBy, m_document, &Document::moveNodeBy); + connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::setNodeBoneJointState, m_document, &Document::setNodeBoneJointState); connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::setNodeOrigin, m_document, &Document::setNodeOrigin); connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::removeNode, m_document, &Document::removeNode); connect(canvasGraphicsWidget, &SkeletonGraphicsWidget::removePart, m_document, &Document::removePart); diff --git a/application/sources/skeleton_graphics_widget.cc b/application/sources/skeleton_graphics_widget.cc index 393590f4..b8836659 100644 --- a/application/sources/skeleton_graphics_widget.cc +++ b/application/sources/skeleton_graphics_widget.cc @@ -260,6 +260,18 @@ void SkeletonGraphicsWidget::showContextMenu(const QPoint& pos) subMenu->addAction(&colorizeAsAutoColorAction); } + QAction markAsBoneJointAction(tr("Bone Joint"), this); + QAction markAsNotBoneJointAction(tr("Not Bone Joint"), this); + if (hasNodeSelection()) { + QMenu* subMenu = contextMenu.addMenu(tr("Mark As")); + + connect(&markAsBoneJointAction, &QAction::triggered, this, &SkeletonGraphicsWidget::markSelectedAsBoneJoint); + subMenu->addAction(&markAsBoneJointAction); + + connect(&markAsNotBoneJointAction, &QAction::triggered, this, &SkeletonGraphicsWidget::markSelectedAsNotBoneJoint); + subMenu->addAction(&markAsNotBoneJointAction); + } + QAction selectAllAction(tr("Select All"), this); if (hasItems()) { connect(&selectAllAction, &QAction::triggered, this, &SkeletonGraphicsWidget::selectAll); @@ -2858,3 +2870,46 @@ void SkeletonGraphicsWidget::ikMove(dust3d::Uuid endEffectorId, QVector3D target connect(thread, &QThread::finished, thread, &QThread::deleteLater); thread->start(); } + +void SkeletonGraphicsWidget::setNodeBoneJointStates(const std::vector& nodeIds, bool boneJoint) +{ + if (nodeIds.empty()) + return; + + emit batchChangeBegin(); + for (const auto& it : nodeIds) { + emit setNodeBoneJointState(it, boneJoint); + } + emit batchChangeEnd(); + emit groupOperationAdded(); +} + +void SkeletonGraphicsWidget::markSelectedAsBoneJoint() +{ + std::set nodeItems; + readMergedSkeletonNodeSetFromRangeSelection(&nodeItems); + if (nodeItems.empty()) + return; + + std::vector nodeIds; + for (const auto& it : nodeItems) { + nodeIds.push_back(it->id()); + } + + setNodeBoneJointStates(nodeIds, true); +} + +void SkeletonGraphicsWidget::markSelectedAsNotBoneJoint() +{ + std::set nodeItems; + readMergedSkeletonNodeSetFromRangeSelection(&nodeItems); + if (nodeItems.empty()) + return; + + std::vector nodeIds; + for (const auto& it : nodeItems) { + nodeIds.push_back(it->id()); + } + + setNodeBoneJointStates(nodeIds, false); +} diff --git a/application/sources/skeleton_graphics_widget.h b/application/sources/skeleton_graphics_widget.h index cf6c5288..537adb94 100644 --- a/application/sources/skeleton_graphics_widget.h +++ b/application/sources/skeleton_graphics_widget.h @@ -396,6 +396,7 @@ signals: void addNode(float x, float y, float z, float radius, dust3d::Uuid fromNodeId); void scaleNodeByAddRadius(dust3d::Uuid nodeId, float amount); void moveNodeBy(dust3d::Uuid nodeId, float x, float y, float z); + void setNodeBoneJointState(const dust3d::Uuid& nodeId, bool boneJoint); void removeNode(dust3d::Uuid nodeId); void removePart(dust3d::Uuid partId); void setEditMode(Document::EditMode mode); @@ -572,6 +573,8 @@ public slots: void shortcutChamferedOrNotSelectedPart(); void shortcutSelectAll(); void shortcutEscape(); + void markSelectedAsBoneJoint(); + void markSelectedAsNotBoneJoint(); private slots: void turnaroundImageReady(); @@ -598,6 +601,7 @@ private: void rotateItems(const std::set& nodeItems, int degree, QVector2D center); void rotateAllSideProfile(int degree); bool isFloatEqual(float a, float b); + void setNodeBoneJointStates(const std::vector& nodeIds, bool boneJoint); private: const Document* m_document = nullptr;