2022-10-18 09:35:04 +00:00
# include "skeleton_graphics_widget.h"
# include "theme.h"
# include <QApplication>
# include <QBitmap>
2018-04-07 08:44:39 +00:00
# include <QDebug>
# include <QGuiApplication>
2022-10-18 09:35:04 +00:00
# include <QMatrix4x4>
# include <QMenu>
# include <QScrollBar>
# include <QVector2D>
2018-04-07 08:44:39 +00:00
# include <QtGlobal>
# include <algorithm>
2022-10-18 09:35:04 +00:00
# include <cmath>
2018-12-11 11:55:55 +00:00
# include <queue>
2018-04-07 08:44:39 +00:00
2022-10-22 03:11:00 +00:00
SkeletonGraphicsWidget : : SkeletonGraphicsWidget ( const Document * document )
2022-10-18 09:35:04 +00:00
: m_document ( document )
2018-04-07 08:44:39 +00:00
{
setRenderHint ( QPainter : : Antialiasing , false ) ;
setBackgroundBrush ( QBrush ( QWidget : : palette ( ) . color ( QWidget : : backgroundRole ( ) ) , Qt : : SolidPattern ) ) ;
setContentsMargins ( 0 , 0 , 0 , 0 ) ;
setFrameStyle ( QFrame : : NoFrame ) ;
2022-10-18 09:35:04 +00:00
2018-04-07 08:44:39 +00:00
setAlignment ( Qt : : AlignCenter ) ;
2022-10-18 09:35:04 +00:00
2018-04-07 08:44:39 +00:00
setScene ( new QGraphicsScene ( ) ) ;
2022-10-18 09:35:04 +00:00
2018-04-07 08:44:39 +00:00
m_backgroundItem = new QGraphicsPixmapItem ( ) ;
2018-04-26 02:23:22 +00:00
enableBackgroundBlur ( ) ;
2018-04-07 08:44:39 +00:00
scene ( ) - > addItem ( m_backgroundItem ) ;
2022-10-18 09:35:04 +00:00
2018-04-07 08:44:39 +00:00
m_cursorNodeItem = new SkeletonGraphicsNodeItem ( ) ;
m_cursorNodeItem - > hide ( ) ;
2018-04-10 07:59:20 +00:00
m_cursorNodeItem - > setData ( 0 , " cursorNode " ) ;
2018-04-07 08:44:39 +00:00
scene ( ) - > addItem ( m_cursorNodeItem ) ;
2022-10-18 09:35:04 +00:00
2018-04-07 08:44:39 +00:00
m_cursorEdgeItem = new SkeletonGraphicsEdgeItem ( ) ;
m_cursorEdgeItem - > hide ( ) ;
2018-04-10 07:59:20 +00:00
m_cursorEdgeItem - > setData ( 0 , " cursorEdge " ) ;
2018-04-07 08:44:39 +00:00
scene ( ) - > addItem ( m_cursorEdgeItem ) ;
2022-10-18 09:35:04 +00:00
2018-04-08 15:08:23 +00:00
m_selectionItem = new SkeletonGraphicsSelectionItem ( ) ;
m_selectionItem - > hide ( ) ;
scene ( ) - > addItem ( m_selectionItem ) ;
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
m_mainOriginItem = new SkeletonGraphicsOriginItem ( Document : : Profile : : Main ) ;
2019-10-19 13:14:36 +00:00
m_mainOriginItem - > setRotated ( m_rotated ) ;
2018-04-15 12:11:51 +00:00
m_mainOriginItem - > hide ( ) ;
scene ( ) - > addItem ( m_mainOriginItem ) ;
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
m_sideOriginItem = new SkeletonGraphicsOriginItem ( Document : : Profile : : Side ) ;
2018-04-15 12:11:51 +00:00
m_sideOriginItem - > hide ( ) ;
scene ( ) - > addItem ( m_sideOriginItem ) ;
2022-10-18 09:35:04 +00:00
2018-04-07 08:44:39 +00:00
scene ( ) - > setSceneRect ( rect ( ) ) ;
2022-10-18 09:35:04 +00:00
2018-04-07 08:44:39 +00:00
setMouseTracking ( true ) ;
2022-10-18 09:35:04 +00:00
2018-04-09 03:39:04 +00:00
setContextMenuPolicy ( Qt : : CustomContextMenu ) ;
connect ( this , & SkeletonGraphicsWidget : : customContextMenuRequested , this , & SkeletonGraphicsWidget : : showContextMenu ) ;
}
2019-10-25 14:11:17 +00:00
SkeletonGraphicsWidget : : ~ SkeletonGraphicsWidget ( )
{
delete m_backgroundImage ;
}
2019-10-19 13:14:36 +00:00
void SkeletonGraphicsWidget : : setRotated ( bool rotated )
{
if ( m_rotated = = rotated )
return ;
m_rotated = rotated ;
if ( nullptr ! = m_mainOriginItem )
m_mainOriginItem - > setRotated ( m_rotated ) ;
updateItems ( ) ;
}
2022-10-18 09:35:04 +00:00
void SkeletonGraphicsWidget : : setModelWidget ( ModelWidget * modelWidget )
2018-10-24 08:54:18 +00:00
{
m_modelWidget = modelWidget ;
}
2018-04-26 02:23:22 +00:00
void SkeletonGraphicsWidget : : enableBackgroundBlur ( )
{
2018-12-16 05:29:22 +00:00
m_backgroundItem - > setOpacity ( m_turnaroundOpacity ) ;
2018-04-26 02:23:22 +00:00
}
void SkeletonGraphicsWidget : : disableBackgroundBlur ( )
{
m_backgroundItem - > setOpacity ( 1 ) ;
}
2018-12-16 05:29:22 +00:00
void SkeletonGraphicsWidget : : setBackgroundBlur ( float turnaroundOpacity )
{
m_turnaroundOpacity = turnaroundOpacity ;
m_backgroundItem - > setOpacity ( m_turnaroundOpacity ) ;
}
2019-10-25 14:11:17 +00:00
void SkeletonGraphicsWidget : : shortcutEscape ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
if ( Document : : EditMode : : Add = = m_document - > editMode | | Document : : EditMode : : Paint = = m_document - > editMode ) {
emit setEditMode ( Document : : EditMode : : Select ) ;
2019-10-25 14:11:17 +00:00
return ;
}
}
2022-10-18 09:35:04 +00:00
void SkeletonGraphicsWidget : : showContextMenu ( const QPoint & pos )
2018-04-09 03:39:04 +00:00
{
2022-11-07 09:41:43 +00:00
if ( Document : : EditMode : : Add = = m_document - > editMode ) {
emit setEditMode ( Document : : EditMode : : Select ) ;
2018-04-09 03:39:04 +00:00
return ;
}
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
if ( Document : : EditMode : : Select ! = m_document - > editMode ) {
2018-04-09 03:39:04 +00:00
return ;
}
2022-10-18 09:35:04 +00:00
2018-04-09 03:39:04 +00:00
QMenu contextMenu ( this ) ;
2022-10-18 09:35:04 +00:00
2018-04-10 07:59:20 +00:00
QAction addAction ( tr ( " Add... " ) , this ) ;
2020-12-15 14:28:20 +00:00
connect ( & addAction , & QAction : : triggered , [ = ] ( ) {
2022-11-07 09:41:43 +00:00
emit setEditMode ( Document : : EditMode : : Add ) ;
2020-12-15 14:28:20 +00:00
} ) ;
contextMenu . addAction ( & addAction ) ;
2022-10-18 09:35:04 +00:00
2018-04-09 15:10:23 +00:00
QAction undoAction ( tr ( " Undo " ) , this ) ;
if ( m_document - > undoable ( ) ) {
2022-10-22 03:11:00 +00:00
connect ( & undoAction , & QAction : : triggered , m_document , & Document : : undo ) ;
2018-04-09 15:10:23 +00:00
contextMenu . addAction ( & undoAction ) ;
}
2022-10-18 09:35:04 +00:00
2018-04-09 15:10:23 +00:00
QAction redoAction ( tr ( " Redo " ) , this ) ;
if ( m_document - > redoable ( ) ) {
2022-10-22 03:11:00 +00:00
connect ( & redoAction , & QAction : : triggered , m_document , & Document : : redo ) ;
2018-04-09 15:10:23 +00:00
contextMenu . addAction ( & redoAction ) ;
}
2022-10-18 09:35:04 +00:00
2018-04-09 15:10:23 +00:00
QAction deleteAction ( tr ( " Delete " ) , this ) ;
2020-12-15 14:28:20 +00:00
if ( hasSelection ( ) ) {
2018-04-09 14:37:20 +00:00
connect ( & deleteAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : deleteSelected ) ;
contextMenu . addAction ( & deleteAction ) ;
}
2022-10-18 09:35:04 +00:00
2018-04-12 12:27:21 +00:00
QAction breakAction ( tr ( " Break " ) , this ) ;
2020-12-15 14:28:20 +00:00
if ( hasEdgeSelection ( ) ) {
2018-04-12 12:27:21 +00:00
connect ( & breakAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : breakSelected ) ;
contextMenu . addAction ( & breakAction ) ;
}
2022-10-18 09:35:04 +00:00
2020-10-20 22:04:12 +00:00
QAction reduceAction ( tr ( " Reduce " ) , this ) ;
2020-12-15 14:28:20 +00:00
if ( hasSelection ( ) ) {
2020-10-20 22:04:12 +00:00
connect ( & reduceAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : reduceSelected ) ;
contextMenu . addAction ( & reduceAction ) ;
}
2022-10-18 09:35:04 +00:00
2020-04-07 23:15:20 +00:00
QAction reverseAction ( tr ( " Reverse " ) , this ) ;
2020-12-15 14:28:20 +00:00
if ( hasEdgeSelection ( ) ) {
2020-04-07 23:15:20 +00:00
connect ( & reverseAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : reverseSelectedEdges ) ;
contextMenu . addAction ( & reverseAction ) ;
}
2022-10-18 09:35:04 +00:00
2018-04-12 12:46:13 +00:00
QAction connectAction ( tr ( " Connect " ) , this ) ;
2020-12-15 14:28:20 +00:00
if ( hasTwoDisconnectedNodesSelection ( ) ) {
2018-04-12 12:46:13 +00:00
connect ( & connectAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : connectSelected ) ;
contextMenu . addAction ( & connectAction ) ;
}
2022-10-18 09:35:04 +00:00
2018-04-09 15:10:23 +00:00
QAction cutAction ( tr ( " Cut " ) , this ) ;
2020-12-15 14:28:20 +00:00
if ( hasSelection ( ) ) {
2018-04-09 14:37:20 +00:00
connect ( & cutAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : cut ) ;
contextMenu . addAction ( & cutAction ) ;
}
2022-10-18 09:35:04 +00:00
2018-04-09 15:10:23 +00:00
QAction copyAction ( tr ( " Copy " ) , this ) ;
2020-12-15 14:28:20 +00:00
if ( hasNodeSelection ( ) ) {
2018-04-09 14:37:20 +00:00
connect ( & copyAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : copy ) ;
contextMenu . addAction ( & copyAction ) ;
}
2022-10-18 09:35:04 +00:00
2018-04-09 15:10:23 +00:00
QAction pasteAction ( tr ( " Paste " ) , this ) ;
2018-11-09 03:20:48 +00:00
if ( m_document - > hasPastableNodesInClipboard ( ) ) {
2022-10-22 03:11:00 +00:00
connect ( & pasteAction , & QAction : : triggered , m_document , & Document : : paste ) ;
2018-04-09 14:37:20 +00:00
contextMenu . addAction ( & pasteAction ) ;
}
2022-10-18 09:35:04 +00:00
2018-04-09 15:10:23 +00:00
QAction flipHorizontallyAction ( tr ( " H Flip " ) , this ) ;
2020-12-15 14:28:20 +00:00
if ( hasMultipleSelection ( ) ) {
2018-04-09 14:37:20 +00:00
connect ( & flipHorizontallyAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : flipHorizontally ) ;
contextMenu . addAction ( & flipHorizontallyAction ) ;
}
2022-10-18 09:35:04 +00:00
2018-04-09 15:10:23 +00:00
QAction flipVerticallyAction ( tr ( " V Flip " ) , this ) ;
2020-12-15 14:28:20 +00:00
if ( hasMultipleSelection ( ) ) {
2018-04-09 14:37:20 +00:00
connect ( & flipVerticallyAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : flipVertically ) ;
contextMenu . addAction ( & flipVerticallyAction ) ;
}
2022-10-18 09:35:04 +00:00
2018-06-15 14:54:19 +00:00
QAction rotateClockwiseAction ( tr ( " Rotate 90D CW " ) , this ) ;
2020-12-15 14:28:20 +00:00
if ( hasMultipleSelection ( ) ) {
2018-06-15 09:58:46 +00:00
connect ( & rotateClockwiseAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : rotateClockwise90Degree ) ;
contextMenu . addAction ( & rotateClockwiseAction ) ;
}
2022-10-18 09:35:04 +00:00
2018-06-15 14:54:19 +00:00
QAction rotateCounterclockwiseAction ( tr ( " Rotate 90D CCW " ) , this ) ;
2020-12-15 14:28:20 +00:00
if ( hasMultipleSelection ( ) ) {
2018-06-15 09:58:46 +00:00
connect ( & rotateCounterclockwiseAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : rotateCounterclockwise90Degree ) ;
contextMenu . addAction ( & rotateCounterclockwiseAction ) ;
}
2022-10-18 09:35:04 +00:00
2018-06-21 08:24:18 +00:00
QAction switchXzAction ( tr ( " Switch XZ " ) , this ) ;
2020-12-15 14:28:20 +00:00
if ( hasSelection ( ) ) {
2018-06-21 08:24:18 +00:00
connect ( & switchXzAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : switchSelectedXZ ) ;
contextMenu . addAction ( & switchXzAction ) ;
}
2022-10-18 09:35:04 +00:00
2018-06-02 09:34:48 +00:00
QAction alignToLocalCenterAction ( tr ( " Local Center " ) , this ) ;
QAction alignToLocalVerticalCenterAction ( tr ( " Local Vertical Center " ) , this ) ;
QAction alignToLocalHorizontalCenterAction ( tr ( " Local Horizontal Center " ) , this ) ;
QAction alignToGlobalCenterAction ( tr ( " Global Center " ) , this ) ;
QAction alignToGlobalVerticalCenterAction ( tr ( " Global Vertical Center " ) , this ) ;
QAction alignToGlobalHorizontalCenterAction ( tr ( " Global Horizontal Center " ) , this ) ;
2020-12-15 14:28:20 +00:00
if ( ( ( hasSelection ( ) & & m_document - > originSettled ( ) ) | | hasMultipleSelection ( ) ) ) {
2022-10-18 09:35:04 +00:00
QMenu * subMenu = contextMenu . addMenu ( tr ( " Align To " ) ) ;
2018-06-02 09:34:48 +00:00
if ( hasMultipleSelection ( ) ) {
connect ( & alignToLocalCenterAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : alignSelectedToLocalCenter ) ;
subMenu - > addAction ( & alignToLocalCenterAction ) ;
2022-10-18 09:35:04 +00:00
2018-06-02 09:34:48 +00:00
connect ( & alignToLocalVerticalCenterAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : alignSelectedToLocalVerticalCenter ) ;
subMenu - > addAction ( & alignToLocalVerticalCenterAction ) ;
2022-10-18 09:35:04 +00:00
2018-06-02 09:34:48 +00:00
connect ( & alignToLocalHorizontalCenterAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : alignSelectedToLocalHorizontalCenter ) ;
subMenu - > addAction ( & alignToLocalHorizontalCenterAction ) ;
}
2022-10-18 09:35:04 +00:00
2018-06-02 09:34:48 +00:00
if ( hasSelection ( ) & & m_document - > originSettled ( ) ) {
connect ( & alignToGlobalCenterAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : alignSelectedToGlobalCenter ) ;
subMenu - > addAction ( & alignToGlobalCenterAction ) ;
2022-10-18 09:35:04 +00:00
2018-06-02 09:34:48 +00:00
connect ( & alignToGlobalVerticalCenterAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : alignSelectedToGlobalVerticalCenter ) ;
subMenu - > addAction ( & alignToGlobalVerticalCenterAction ) ;
2022-10-18 09:35:04 +00:00
2018-06-02 09:34:48 +00:00
connect ( & alignToGlobalHorizontalCenterAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : alignSelectedToGlobalHorizontalCenter ) ;
subMenu - > addAction ( & alignToGlobalHorizontalCenterAction ) ;
}
}
2022-10-18 09:35:04 +00:00
2019-10-25 14:11:17 +00:00
QAction colorizeAsBlankAction ( tr ( " Blank " ) , this ) ;
QAction colorizeAsAutoColorAction ( tr ( " Auto Color " ) , this ) ;
2020-12-15 14:28:20 +00:00
if ( hasNodeSelection ( ) ) {
2022-10-18 09:35:04 +00:00
QMenu * subMenu = contextMenu . addMenu ( tr ( " Colorize " ) ) ;
2019-10-25 14:11:17 +00:00
connect ( & colorizeAsBlankAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : fadeSelected ) ;
subMenu - > addAction ( & colorizeAsBlankAction ) ;
2022-10-18 09:35:04 +00:00
2019-10-25 14:11:17 +00:00
connect ( & colorizeAsAutoColorAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : colorizeSelected ) ;
subMenu - > addAction ( & colorizeAsAutoColorAction ) ;
}
2022-10-18 09:35:04 +00:00
2022-11-11 20:31:49 +00:00
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 ) ;
}
2018-04-09 15:10:23 +00:00
QAction selectAllAction ( tr ( " Select All " ) , this ) ;
2018-04-10 07:59:20 +00:00
if ( hasItems ( ) ) {
2018-04-09 14:37:20 +00:00
connect ( & selectAllAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : selectAll ) ;
contextMenu . addAction ( & selectAllAction ) ;
}
2022-10-18 09:35:04 +00:00
2018-04-09 15:10:23 +00:00
QAction selectPartAllAction ( tr ( " Select Part " ) , this ) ;
2020-12-15 14:28:20 +00:00
if ( hasItems ( ) ) {
2018-04-09 14:37:20 +00:00
connect ( & selectPartAllAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : selectPartAll ) ;
contextMenu . addAction ( & selectPartAllAction ) ;
}
2022-10-18 09:35:04 +00:00
2018-04-09 15:10:23 +00:00
QAction unselectAllAction ( tr ( " Unselect All " ) , this ) ;
2018-04-10 07:59:20 +00:00
if ( hasSelection ( ) ) {
2018-04-09 14:37:20 +00:00
connect ( & unselectAllAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : unselectAll ) ;
contextMenu . addAction ( & unselectAllAction ) ;
}
2018-04-09 03:39:04 +00:00
contextMenu . exec ( mapToGlobal ( pos ) ) ;
2018-04-07 08:44:39 +00:00
}
2018-04-10 07:59:20 +00:00
bool SkeletonGraphicsWidget : : hasSelection ( )
{
return ! m_rangeSelectionSet . empty ( ) ;
}
bool SkeletonGraphicsWidget : : hasItems ( )
{
return ! nodeItemMap . empty ( ) ;
}
bool SkeletonGraphicsWidget : : hasMultipleSelection ( )
{
return ! m_rangeSelectionSet . empty ( ) & & ! isSingleNodeSelected ( ) ;
}
2018-04-12 12:27:21 +00:00
bool SkeletonGraphicsWidget : : hasEdgeSelection ( )
{
2022-10-18 09:35:04 +00:00
for ( const auto & it : m_rangeSelectionSet ) {
2018-04-12 12:27:21 +00:00
if ( it - > data ( 0 ) = = " edge " )
return true ;
}
return false ;
}
2018-05-30 01:51:38 +00:00
bool SkeletonGraphicsWidget : : hasNodeSelection ( )
{
2022-10-18 09:35:04 +00:00
for ( const auto & it : m_rangeSelectionSet ) {
2018-05-30 01:51:38 +00:00
if ( it - > data ( 0 ) = = " node " )
return true ;
}
return false ;
}
2018-04-12 12:46:13 +00:00
bool SkeletonGraphicsWidget : : hasTwoDisconnectedNodesSelection ( )
{
2021-11-18 14:58:01 +00:00
std : : vector < dust3d : : Uuid > nodeIds ;
2022-10-18 09:35:04 +00:00
for ( const auto & it : m_rangeSelectionSet ) {
2018-04-12 12:46:13 +00:00
if ( it - > data ( 0 ) = = " node " ) {
2022-10-18 09:35:04 +00:00
nodeIds . push_back ( ( ( SkeletonGraphicsNodeItem * ) it ) - > id ( ) ) ;
2018-04-12 12:46:13 +00:00
}
}
if ( nodeIds . size ( ) ! = 2 )
return false ;
if ( m_document - > findEdgeByNodes ( nodeIds [ 0 ] , nodeIds [ 1 ] ) )
return false ;
2019-06-26 11:35:56 +00:00
if ( ! m_document - > isNodeConnectable ( nodeIds [ 0 ] ) )
return false ;
if ( ! m_document - > isNodeConnectable ( nodeIds [ 1 ] ) )
return false ;
2018-04-12 12:46:13 +00:00
return true ;
}
2019-10-25 14:11:17 +00:00
void SkeletonGraphicsWidget : : fadeSelected ( )
{
2021-11-18 14:58:01 +00:00
std : : set < dust3d : : Uuid > partIds ;
2022-10-18 09:35:04 +00:00
for ( const auto & it : m_rangeSelectionSet ) {
2019-10-25 14:11:17 +00:00
if ( it - > data ( 0 ) = = " node " ) {
2022-10-18 09:35:04 +00:00
SkeletonGraphicsNodeItem * nodeItem = ( SkeletonGraphicsNodeItem * ) it ;
2022-11-07 09:41:43 +00:00
const Document : : Node * node = m_document - > findNode ( nodeItem - > id ( ) ) ;
2019-10-25 14:11:17 +00:00
if ( nullptr = = node )
continue ;
if ( partIds . find ( node - > partId ) ! = partIds . end ( ) )
continue ;
partIds . insert ( node - > partId ) ;
}
}
if ( partIds . empty ( ) )
return ;
emit batchChangeBegin ( ) ;
2022-10-18 09:35:04 +00:00
for ( const auto & it : partIds ) {
2019-10-25 14:11:17 +00:00
emit setPartColorState ( it , false , Qt : : white ) ;
}
emit batchChangeEnd ( ) ;
emit groupOperationAdded ( ) ;
}
void SkeletonGraphicsWidget : : colorizeSelected ( )
{
if ( nullptr = = m_backgroundImage )
return ;
2021-11-18 14:58:01 +00:00
std : : map < dust3d : : Uuid , std : : map < QString , size_t > > sumOfColor ;
2022-10-18 09:35:04 +00:00
for ( const auto & it : m_rangeSelectionSet ) {
2019-10-25 14:11:17 +00:00
if ( it - > data ( 0 ) = = " node " ) {
2022-10-18 09:35:04 +00:00
SkeletonGraphicsNodeItem * nodeItem = ( SkeletonGraphicsNodeItem * ) it ;
2022-11-07 09:41:43 +00:00
const Document : : Node * node = m_document - > findNode ( nodeItem - > id ( ) ) ;
2019-10-25 14:11:17 +00:00
if ( nullptr = = node )
continue ;
2022-10-18 09:35:04 +00:00
const auto & position = nodeItem - > origin ( ) ;
2019-10-25 14:11:17 +00:00
sumOfColor [ node - > partId ] [ m_backgroundImage - > pixelColor ( position . x ( ) , position . y ( ) ) . name ( ) ] + + ;
} else if ( it - > data ( 0 ) = = " edge " ) {
2022-10-18 09:35:04 +00:00
SkeletonGraphicsEdgeItem * edgeItem = ( SkeletonGraphicsEdgeItem * ) it ;
2022-11-07 09:41:43 +00:00
const Document : : Edge * edge = m_document - > findEdge ( edgeItem - > id ( ) ) ;
2019-10-25 14:11:17 +00:00
if ( nullptr = = edge )
continue ;
const auto position = ( edgeItem - > firstItem ( ) - > origin ( ) + edgeItem - > secondItem ( ) - > origin ( ) ) / 2 ;
sumOfColor [ edge - > partId ] [ m_backgroundImage - > pixelColor ( position . x ( ) , position . y ( ) ) . name ( ) ] + + ;
}
}
if ( sumOfColor . empty ( ) )
return ;
emit batchChangeBegin ( ) ;
2022-10-18 09:35:04 +00:00
for ( const auto & it : sumOfColor ) {
2019-10-25 14:11:17 +00:00
int r = 0 ;
int g = 0 ;
int b = 0 ;
2022-10-18 09:35:04 +00:00
for ( const auto & freq : it . second ) {
2019-10-25 14:11:17 +00:00
QColor color ( freq . first ) ;
r + = color . red ( ) ;
g + = color . green ( ) ;
b + = color . blue ( ) ;
}
QColor color ( r / it . second . size ( ) , g / it . second . size ( ) , b / it . second . size ( ) ) ;
emit setPartColorState ( it . first , true , color ) ;
}
emit batchChangeEnd ( ) ;
emit groupOperationAdded ( ) ;
}
2018-04-12 12:27:21 +00:00
void SkeletonGraphicsWidget : : breakSelected ( )
{
2021-11-18 14:58:01 +00:00
std : : set < dust3d : : Uuid > edgeIds ;
2022-10-18 09:35:04 +00:00
for ( const auto & it : m_rangeSelectionSet ) {
2018-04-12 12:27:21 +00:00
if ( it - > data ( 0 ) = = " edge " )
2022-10-18 09:35:04 +00:00
edgeIds . insert ( ( ( SkeletonGraphicsEdgeItem * ) it ) - > id ( ) ) ;
2018-04-12 12:27:21 +00:00
}
2018-04-12 12:46:13 +00:00
if ( edgeIds . empty ( ) )
return ;
2018-04-12 12:27:21 +00:00
emit batchChangeBegin ( ) ;
2022-10-18 09:35:04 +00:00
for ( const auto & it : edgeIds ) {
2018-04-12 12:27:21 +00:00
emit breakEdge ( it ) ;
}
emit batchChangeEnd ( ) ;
2018-04-12 12:46:13 +00:00
emit groupOperationAdded ( ) ;
}
2020-10-20 22:04:12 +00:00
void SkeletonGraphicsWidget : : reduceSelected ( )
{
2021-11-18 14:58:01 +00:00
std : : set < dust3d : : Uuid > nodeIds ;
2022-10-18 09:35:04 +00:00
for ( const auto & it : m_rangeSelectionSet ) {
2020-10-20 22:04:12 +00:00
if ( it - > data ( 0 ) = = " node " )
2022-10-18 09:35:04 +00:00
nodeIds . insert ( ( ( SkeletonGraphicsNodeItem * ) it ) - > id ( ) ) ;
2020-10-20 22:04:12 +00:00
}
if ( nodeIds . empty ( ) )
return ;
emit batchChangeBegin ( ) ;
2022-10-18 09:35:04 +00:00
for ( const auto & it : nodeIds ) {
2020-10-20 22:04:12 +00:00
emit reduceNode ( it ) ;
}
emit batchChangeEnd ( ) ;
emit groupOperationAdded ( ) ;
}
2020-04-07 23:15:20 +00:00
void SkeletonGraphicsWidget : : reverseSelectedEdges ( )
{
2021-11-18 14:58:01 +00:00
std : : set < dust3d : : Uuid > edgeIds ;
2022-10-18 09:35:04 +00:00
for ( const auto & it : m_rangeSelectionSet ) {
2020-04-07 23:15:20 +00:00
if ( it - > data ( 0 ) = = " edge " )
2022-10-18 09:35:04 +00:00
edgeIds . insert ( ( ( SkeletonGraphicsEdgeItem * ) it ) - > id ( ) ) ;
2020-04-07 23:15:20 +00:00
}
if ( edgeIds . empty ( ) )
return ;
emit batchChangeBegin ( ) ;
2022-10-18 09:35:04 +00:00
for ( const auto & it : edgeIds ) {
2020-04-07 23:15:20 +00:00
emit reverseEdge ( it ) ;
}
emit batchChangeEnd ( ) ;
emit groupOperationAdded ( ) ;
}
2018-04-12 12:46:13 +00:00
void SkeletonGraphicsWidget : : connectSelected ( )
{
2021-11-18 14:58:01 +00:00
std : : vector < dust3d : : Uuid > nodeIds ;
2022-10-18 09:35:04 +00:00
for ( const auto & it : m_rangeSelectionSet ) {
2018-04-12 12:46:13 +00:00
if ( it - > data ( 0 ) = = " node " ) {
2022-10-18 09:35:04 +00:00
nodeIds . push_back ( ( ( SkeletonGraphicsNodeItem * ) it ) - > id ( ) ) ;
2018-04-12 12:46:13 +00:00
}
}
if ( nodeIds . size ( ) ! = 2 )
return ;
if ( m_document - > findEdgeByNodes ( nodeIds [ 0 ] , nodeIds [ 1 ] ) )
return ;
2019-06-26 11:35:56 +00:00
if ( ! m_document - > isNodeConnectable ( nodeIds [ 0 ] ) )
return ;
if ( ! m_document - > isNodeConnectable ( nodeIds [ 1 ] ) )
return ;
2018-04-12 12:46:13 +00:00
emit addEdge ( nodeIds [ 0 ] , nodeIds [ 1 ] ) ;
emit groupOperationAdded ( ) ;
2018-04-12 12:27:21 +00:00
}
2018-06-02 09:34:48 +00:00
void SkeletonGraphicsWidget : : alignSelectedToLocal ( bool alignToVerticalCenter , bool alignToHorizontalCenter )
{
if ( ! hasMultipleSelection ( ) )
return ;
2022-10-18 09:35:04 +00:00
std : : set < SkeletonGraphicsNodeItem * > nodeItems ;
2018-06-02 09:34:48 +00:00
readMergedSkeletonNodeSetFromRangeSelection ( & nodeItems ) ;
if ( nodeItems . empty ( ) )
return ;
if ( nodeItems . size ( ) < 2 )
return ;
emit batchChangeBegin ( ) ;
QVector2D center = centerOfNodeItemSet ( nodeItems ) ;
2022-10-18 09:35:04 +00:00
for ( const auto & it : nodeItems ) {
SkeletonGraphicsNodeItem * nodeItem = it ;
2018-06-02 09:34:48 +00:00
QPointF nodeOrigin = nodeItem - > origin ( ) ;
float byX = alignToHorizontalCenter ? sceneRadiusToUnified ( center . x ( ) - nodeOrigin . x ( ) ) : 0 ;
float byY = alignToVerticalCenter ? sceneRadiusToUnified ( center . y ( ) - nodeOrigin . y ( ) ) : 0 ;
2022-11-07 09:41:43 +00:00
if ( Document : : Profile : : Main = = nodeItem - > profile ( ) ) {
2019-10-19 13:14:36 +00:00
if ( m_rotated )
emit moveNodeBy ( nodeItem - > id ( ) , byY , byX , 0 ) ;
else
emit moveNodeBy ( nodeItem - > id ( ) , byX , byY , 0 ) ;
2018-06-02 09:34:48 +00:00
} else {
2019-10-19 13:14:36 +00:00
if ( m_rotated )
emit moveNodeBy ( nodeItem - > id ( ) , byY , 0 , byX ) ;
else
emit moveNodeBy ( nodeItem - > id ( ) , 0 , byY , byX ) ;
2018-06-02 09:34:48 +00:00
}
}
emit batchChangeEnd ( ) ;
emit groupOperationAdded ( ) ;
}
void SkeletonGraphicsWidget : : alignSelectedToGlobal ( bool alignToVerticalCenter , bool alignToHorizontalCenter )
2018-04-16 07:12:53 +00:00
{
if ( ! m_document - > originSettled ( ) )
return ;
if ( ! hasSelection ( ) )
return ;
2022-10-18 09:35:04 +00:00
std : : set < SkeletonGraphicsNodeItem * > nodeItems ;
2018-04-16 07:12:53 +00:00
readMergedSkeletonNodeSetFromRangeSelection ( & nodeItems ) ;
if ( nodeItems . empty ( ) )
return ;
emit batchChangeBegin ( ) ;
2022-10-18 09:35:04 +00:00
for ( const auto & nodeItem : nodeItems ) {
2022-11-07 09:41:43 +00:00
const Document : : Node * node = m_document - > findNode ( nodeItem - > id ( ) ) ;
2018-04-16 07:12:53 +00:00
if ( ! node ) {
qDebug ( ) < < " Find node id failed: " < < nodeItem - > id ( ) ;
continue ;
}
2019-10-19 13:14:36 +00:00
float byX = 0 ;
float byY = 0 ;
float byZ = 0 ;
2022-11-07 09:41:43 +00:00
if ( Document : : Profile : : Main = = nodeItem - > profile ( ) ) {
2018-06-02 09:34:48 +00:00
if ( alignToVerticalCenter & & alignToHorizontalCenter ) {
2019-10-19 13:14:36 +00:00
byX = m_document - > getOriginX ( m_rotated ) - node - > getX ( m_rotated ) ;
byY = m_document - > getOriginY ( m_rotated ) - node - > getY ( m_rotated ) ;
2018-06-02 09:34:48 +00:00
} else if ( alignToVerticalCenter ) {
2019-10-19 13:14:36 +00:00
byY = m_document - > getOriginY ( m_rotated ) - node - > getY ( m_rotated ) ;
2018-06-02 09:34:48 +00:00
} else if ( alignToHorizontalCenter ) {
2019-10-19 13:14:36 +00:00
byX = m_document - > getOriginX ( m_rotated ) - node - > getX ( m_rotated ) ;
2018-06-02 09:34:48 +00:00
}
2018-04-16 07:12:53 +00:00
} else {
2018-06-02 09:34:48 +00:00
if ( alignToVerticalCenter & & alignToHorizontalCenter ) {
2019-10-19 13:14:36 +00:00
byY = m_document - > getOriginY ( m_rotated ) - node - > getY ( m_rotated ) ;
byZ = m_document - > getOriginZ ( m_rotated ) - node - > getZ ( m_rotated ) ;
2018-06-02 09:34:48 +00:00
} else if ( alignToVerticalCenter ) {
2019-10-19 13:14:36 +00:00
byY = m_document - > getOriginY ( m_rotated ) - node - > getY ( m_rotated ) ;
2018-06-02 09:34:48 +00:00
} else if ( alignToHorizontalCenter ) {
2019-10-19 13:14:36 +00:00
byZ = m_document - > getOriginZ ( m_rotated ) - node - > getZ ( m_rotated ) ;
2018-06-02 09:34:48 +00:00
}
2018-04-16 07:12:53 +00:00
}
2019-10-19 13:14:36 +00:00
if ( m_rotated )
emit moveNodeBy ( node - > id , byY , byX , byZ ) ;
else
emit moveNodeBy ( node - > id , byX , byY , byZ ) ;
2018-04-16 07:12:53 +00:00
}
emit batchChangeEnd ( ) ;
emit groupOperationAdded ( ) ;
}
2018-06-02 09:34:48 +00:00
void SkeletonGraphicsWidget : : alignSelectedToGlobalVerticalCenter ( )
{
alignSelectedToGlobal ( true , false ) ;
}
void SkeletonGraphicsWidget : : alignSelectedToGlobalHorizontalCenter ( )
{
alignSelectedToGlobal ( false , true ) ;
}
void SkeletonGraphicsWidget : : alignSelectedToGlobalCenter ( )
{
alignSelectedToGlobal ( true , true ) ;
}
void SkeletonGraphicsWidget : : alignSelectedToLocalVerticalCenter ( )
{
alignSelectedToLocal ( true , false ) ;
}
void SkeletonGraphicsWidget : : alignSelectedToLocalHorizontalCenter ( )
{
alignSelectedToLocal ( false , true ) ;
}
void SkeletonGraphicsWidget : : alignSelectedToLocalCenter ( )
{
alignSelectedToLocal ( true , true ) ;
}
2018-04-07 08:44:39 +00:00
void SkeletonGraphicsWidget : : updateItems ( )
{
for ( auto nodeItemIt = nodeItemMap . begin ( ) ; nodeItemIt ! = nodeItemMap . end ( ) ; nodeItemIt + + ) {
nodeRadiusChanged ( nodeItemIt - > first ) ;
nodeOriginChanged ( nodeItemIt - > first ) ;
}
2018-04-15 12:50:56 +00:00
originChanged ( ) ;
2018-04-07 08:44:39 +00:00
}
void SkeletonGraphicsWidget : : canvasResized ( )
{
updateTurnaround ( ) ;
}
void SkeletonGraphicsWidget : : turnaroundChanged ( )
{
updateTurnaround ( ) ;
setTransform ( QTransform ( ) ) ;
}
void SkeletonGraphicsWidget : : updateTurnaround ( )
{
2022-10-18 09:35:04 +00:00
const QImage * turnaroundImage = & m_document - > turnaround ;
2020-12-07 22:57:37 +00:00
QImage onePixel ( 2 , 1 , QImage : : Format_ARGB32 ) ;
2018-05-11 15:06:54 +00:00
if ( turnaroundImage - > isNull ( ) ) {
2020-12-12 07:23:21 +00:00
onePixel . fill ( Qt : : white ) ;
2018-05-11 15:06:54 +00:00
turnaroundImage = & onePixel ;
}
2022-10-18 09:35:04 +00:00
2018-04-07 08:44:39 +00:00
m_turnaroundChanged = true ;
if ( m_turnaroundLoader )
return ;
2022-10-18 09:35:04 +00:00
2018-04-07 08:44:39 +00:00
m_turnaroundChanged = false ;
2022-10-18 09:35:04 +00:00
QThread * thread = new QThread ;
2018-05-11 15:06:54 +00:00
m_turnaroundLoader = new TurnaroundLoader ( * turnaroundImage ,
2018-04-07 08:44:39 +00:00
parentWidget ( ) - > rect ( ) . size ( ) ) ;
m_turnaroundLoader - > moveToThread ( thread ) ;
connect ( thread , SIGNAL ( started ( ) ) , m_turnaroundLoader , SLOT ( process ( ) ) ) ;
connect ( m_turnaroundLoader , SIGNAL ( finished ( ) ) , this , SLOT ( turnaroundImageReady ( ) ) ) ;
connect ( m_turnaroundLoader , SIGNAL ( finished ( ) ) , thread , SLOT ( quit ( ) ) ) ;
connect ( thread , SIGNAL ( finished ( ) ) , thread , SLOT ( deleteLater ( ) ) ) ;
thread - > start ( ) ;
}
void SkeletonGraphicsWidget : : turnaroundImageReady ( )
{
2019-10-25 14:11:17 +00:00
delete m_backgroundImage ;
m_backgroundImage = m_turnaroundLoader - > takeResultImage ( ) ;
if ( m_backgroundImage & & m_backgroundImage - > width ( ) > 0 & & m_backgroundImage - > height ( ) > 0 ) {
2018-08-27 08:50:40 +00:00
//qDebug() << "Fit turnaround finished with image size:" << backgroundImage->size();
2019-10-25 14:11:17 +00:00
setFixedSize ( m_backgroundImage - > size ( ) ) ;
2018-04-07 08:44:39 +00:00
scene ( ) - > setSceneRect ( rect ( ) ) ;
2019-10-25 14:11:17 +00:00
m_backgroundItem - > setPixmap ( QPixmap : : fromImage ( * m_backgroundImage ) ) ;
2018-04-07 08:44:39 +00:00
updateItems ( ) ;
} else {
qDebug ( ) < < " Fit turnaround failed " ;
}
delete m_turnaroundLoader ;
m_turnaroundLoader = nullptr ;
2022-10-18 09:35:04 +00:00
2020-12-13 13:21:45 +00:00
emit loadedTurnaroundImageChanged ( ) ;
2018-04-07 08:44:39 +00:00
if ( m_turnaroundChanged ) {
updateTurnaround ( ) ;
}
}
2022-10-18 09:35:04 +00:00
const QImage * SkeletonGraphicsWidget : : loadedTurnaroundImage ( ) const
2020-12-13 13:21:45 +00:00
{
return m_backgroundImage ;
}
2018-04-07 08:44:39 +00:00
void SkeletonGraphicsWidget : : updateCursor ( )
{
2022-11-07 09:41:43 +00:00
if ( Document : : EditMode : : Add ! = m_document - > editMode ) {
2018-04-07 08:44:39 +00:00
m_cursorEdgeItem - > hide ( ) ;
m_cursorNodeItem - > hide ( ) ;
}
2022-10-18 09:35:04 +00:00
2021-11-18 14:58:01 +00:00
// Set cursor here if needed
2022-10-18 09:35:04 +00:00
2018-04-07 08:44:39 +00:00
emit cursorChanged ( ) ;
}
void SkeletonGraphicsWidget : : editModeChanged ( )
{
2018-04-08 15:08:23 +00:00
updateCursor ( ) ;
2022-11-07 09:41:43 +00:00
if ( Document : : EditMode : : Add = = m_document - > editMode ) {
2022-10-18 09:35:04 +00:00
SkeletonGraphicsNodeItem * choosenNodeItem = nullptr ;
2018-04-08 15:08:23 +00:00
if ( ! m_rangeSelectionSet . empty ( ) ) {
2022-10-18 09:35:04 +00:00
std : : set < SkeletonGraphicsNodeItem * > nodeItems ;
2018-04-08 15:08:23 +00:00
readMergedSkeletonNodeSetFromRangeSelection ( & nodeItems ) ;
2019-06-26 11:35:56 +00:00
if ( nodeItems . size ( ) = = 1 ) {
2018-04-08 15:08:23 +00:00
choosenNodeItem = * nodeItems . begin ( ) ;
2019-06-26 11:35:56 +00:00
if ( ! m_document - > isNodeConnectable ( choosenNodeItem - > id ( ) ) )
choosenNodeItem = nullptr ;
}
2018-04-07 08:44:39 +00:00
}
2018-04-08 15:08:23 +00:00
m_addFromNodeItem = choosenNodeItem ;
2018-04-07 08:44:39 +00:00
}
}
2022-10-18 09:35:04 +00:00
void SkeletonGraphicsWidget : : mouseMoveEvent ( QMouseEvent * event )
2018-04-07 08:44:39 +00:00
{
2018-10-24 08:54:18 +00:00
if ( m_modelWidget & & m_modelWidget - > inputMouseMoveEventFromOtherWidget ( event ) )
return ;
2022-10-18 09:35:04 +00:00
2018-04-07 08:44:39 +00:00
QGraphicsView : : mouseMoveEvent ( event ) ;
mouseMove ( event ) ;
}
2020-11-09 10:46:06 +00:00
bool SkeletonGraphicsWidget : : rotated ( )
2019-10-19 13:14:36 +00:00
{
return m_rotated ;
}
2022-10-18 09:35:04 +00:00
bool SkeletonGraphicsWidget : : inputWheelEventFromOtherWidget ( QWheelEvent * event )
2018-11-15 14:33:56 +00:00
{
if ( ! wheel ( event ) ) {
if ( m_modelWidget & & m_modelWidget - > inputWheelEventFromOtherWidget ( event ) )
return true ;
}
return true ;
}
2022-10-18 09:35:04 +00:00
void SkeletonGraphicsWidget : : wheelEvent ( QWheelEvent * event )
2018-04-07 08:44:39 +00:00
{
2018-10-24 08:54:18 +00:00
if ( ! wheel ( event ) ) {
if ( m_modelWidget & & m_modelWidget - > inputWheelEventFromOtherWidget ( event ) )
return ;
}
2018-04-07 08:44:39 +00:00
}
2022-10-18 09:35:04 +00:00
void SkeletonGraphicsWidget : : mouseReleaseEvent ( QMouseEvent * event )
2018-04-07 08:44:39 +00:00
{
2018-10-24 08:54:18 +00:00
if ( m_modelWidget & & m_modelWidget - > inputMouseReleaseEventFromOtherWidget ( event ) )
return ;
2022-10-18 09:35:04 +00:00
2018-04-07 08:44:39 +00:00
QGraphicsView : : mouseReleaseEvent ( event ) ;
mouseRelease ( event ) ;
}
2022-10-18 09:35:04 +00:00
void SkeletonGraphicsWidget : : mousePressEvent ( QMouseEvent * event )
2018-04-07 08:44:39 +00:00
{
2018-10-24 08:54:18 +00:00
if ( m_modelWidget & & m_modelWidget - > inputMousePressEventFromOtherWidget ( event ) )
return ;
2022-10-18 09:35:04 +00:00
2018-04-07 08:44:39 +00:00
QGraphicsView : : mousePressEvent ( event ) ;
2018-04-08 15:08:23 +00:00
m_mouseEventFromSelf = true ;
if ( mousePress ( event ) ) {
m_mouseEventFromSelf = false ;
return ;
}
m_mouseEventFromSelf = false ;
2018-04-07 08:44:39 +00:00
}
2022-10-18 09:35:04 +00:00
void SkeletonGraphicsWidget : : mouseDoubleClickEvent ( QMouseEvent * event )
2018-04-07 08:44:39 +00:00
{
QGraphicsView : : mouseDoubleClickEvent ( event ) ;
mouseDoubleClick ( event ) ;
}
2022-10-18 09:35:04 +00:00
void SkeletonGraphicsWidget : : keyPressEvent ( QKeyEvent * event )
2018-04-07 08:44:39 +00:00
{
2018-08-29 15:42:04 +00:00
if ( keyPress ( event ) )
return ;
2018-04-07 08:44:39 +00:00
QGraphicsView : : keyPressEvent ( event ) ;
}
2022-10-18 09:35:04 +00:00
void SkeletonGraphicsWidget : : keyReleaseEvent ( QKeyEvent * event )
2018-10-24 13:44:21 +00:00
{
if ( keyRelease ( event ) )
return ;
QGraphicsView : : keyReleaseEvent ( event ) ;
}
2022-10-18 09:35:04 +00:00
bool SkeletonGraphicsWidget : : mouseMove ( QMouseEvent * event )
2018-04-07 08:44:39 +00:00
{
if ( m_dragStarted ) {
QPoint currentGlobalPos = event - > globalPos ( ) ;
if ( verticalScrollBar ( ) )
verticalScrollBar ( ) - > setValue ( verticalScrollBar ( ) - > value ( ) + m_lastGlobalPos . y ( ) - currentGlobalPos . y ( ) ) ;
if ( horizontalScrollBar ( ) )
horizontalScrollBar ( ) - > setValue ( horizontalScrollBar ( ) - > value ( ) + m_lastGlobalPos . x ( ) - currentGlobalPos . x ( ) ) ;
m_lastGlobalPos = currentGlobalPos ;
return true ;
}
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
if ( Document : : EditMode : : Select = = m_document - > editMode ) {
2018-04-08 15:08:23 +00:00
if ( m_rangeSelectionStarted ) {
QPointF mouseScenePos = mouseEventScenePos ( event ) ;
m_selectionItem - > updateRange ( m_rangeSelectionStartPos , mouseScenePos ) ;
if ( ! m_selectionItem - > isVisible ( ) )
m_selectionItem - > setVisible ( true ) ;
checkRangeSelection ( ) ;
return true ;
}
}
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
if ( Document : : EditMode : : Select = = m_document - > editMode | | Document : : EditMode : : Add = = m_document - > editMode ) {
2022-10-18 09:35:04 +00:00
2018-04-20 07:38:08 +00:00
//
// > 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.
// > https://www.reddit.com/user/hdu
//
2022-10-18 09:35:04 +00:00
SkeletonGraphicsNodeItem * newHoverNodeItem = nullptr ;
SkeletonGraphicsEdgeItem * newHoverEdgeItem = nullptr ;
SkeletonGraphicsOriginItem * newHoverOriginItem = nullptr ;
2018-04-20 07:38:08 +00:00
QPointF scenePos = mouseEventScenePos ( event ) ;
2022-10-18 09:35:04 +00:00
QList < QGraphicsItem * > items = scene ( ) - > items ( scenePos ) ;
std : : vector < std : : pair < QGraphicsItem * , float > > itemDistance2MapWithMouse ;
2018-04-07 08:44:39 +00:00
for ( auto it = items . begin ( ) ; it ! = items . end ( ) ; it + + ) {
2022-10-18 09:35:04 +00:00
QGraphicsItem * item = * it ;
2018-04-07 08:44:39 +00:00
if ( item - > data ( 0 ) = = " node " ) {
2022-10-18 09:35:04 +00:00
SkeletonGraphicsNodeItem * nodeItem = ( SkeletonGraphicsNodeItem * ) item ;
2019-03-03 00:05:13 +00:00
if ( nodeItem - > deactivated ( ) )
continue ;
2018-04-20 07:38:08 +00:00
QPointF origin = nodeItem - > origin ( ) ;
float distance2 = pow ( origin . x ( ) - scenePos . x ( ) , 2 ) + pow ( origin . y ( ) - scenePos . y ( ) , 2 ) ;
itemDistance2MapWithMouse . push_back ( std : : make_pair ( item , distance2 ) ) ;
2018-04-07 08:44:39 +00:00
} else if ( item - > data ( 0 ) = = " edge " ) {
2022-10-18 09:35:04 +00:00
SkeletonGraphicsEdgeItem * edgeItem = ( SkeletonGraphicsEdgeItem * ) item ;
2019-03-03 00:05:13 +00:00
if ( edgeItem - > deactivated ( ) )
continue ;
2018-04-20 07:38:08 +00:00
if ( edgeItem - > firstItem ( ) & & edgeItem - > secondItem ( ) ) {
QPointF firstOrigin = edgeItem - > firstItem ( ) - > origin ( ) ;
QPointF secondOrigin = edgeItem - > secondItem ( ) - > origin ( ) ;
QPointF origin = ( firstOrigin + secondOrigin ) / 2 ;
float distance2 = pow ( origin . x ( ) - scenePos . x ( ) , 2 ) + pow ( origin . y ( ) - scenePos . y ( ) , 2 ) ;
itemDistance2MapWithMouse . push_back ( std : : make_pair ( item , distance2 ) ) ;
}
2018-04-15 12:11:51 +00:00
} else if ( item - > data ( 0 ) = = " origin " ) {
2022-10-18 09:35:04 +00:00
newHoverOriginItem = ( SkeletonGraphicsOriginItem * ) item ;
2018-04-07 08:44:39 +00:00
}
}
2018-04-20 07:38:08 +00:00
if ( ! itemDistance2MapWithMouse . empty ( ) ) {
std : : sort ( itemDistance2MapWithMouse . begin ( ) , itemDistance2MapWithMouse . end ( ) ,
2022-10-18 09:35:04 +00:00
[ ] ( const std : : pair < QGraphicsItem * , float > & a , const std : : pair < QGraphicsItem * , float > & b ) {
return a . second < b . second ;
} ) ;
QGraphicsItem * pickedNearestItem = itemDistance2MapWithMouse [ 0 ] . first ;
2018-04-20 07:38:08 +00:00
if ( pickedNearestItem - > data ( 0 ) = = " node " ) {
2022-10-18 09:35:04 +00:00
newHoverNodeItem = ( SkeletonGraphicsNodeItem * ) pickedNearestItem ;
2018-04-20 07:38:08 +00:00
} else if ( pickedNearestItem - > data ( 0 ) = = " edge " ) {
2022-10-18 09:35:04 +00:00
newHoverEdgeItem = ( SkeletonGraphicsEdgeItem * ) pickedNearestItem ;
2018-04-20 07:38:08 +00:00
}
}
2018-04-07 08:44:39 +00:00
if ( newHoverNodeItem ) {
newHoverEdgeItem = nullptr ;
}
2018-04-15 12:11:51 +00:00
if ( newHoverOriginItem ! = m_hoveredOriginItem ) {
if ( nullptr ! = m_hoveredOriginItem ) {
m_hoveredOriginItem - > setHovered ( false ) ;
}
m_hoveredOriginItem = newHoverOriginItem ;
if ( nullptr ! = m_hoveredOriginItem ) {
m_hoveredOriginItem - > setHovered ( true ) ;
}
}
2021-11-18 14:58:01 +00:00
dust3d : : Uuid hoveredPartId ;
2018-04-07 08:44:39 +00:00
if ( newHoverNodeItem ! = m_hoveredNodeItem ) {
if ( nullptr ! = m_hoveredNodeItem ) {
2018-04-21 00:23:27 +00:00
setItemHoveredOnAllProfiles ( m_hoveredNodeItem , false ) ;
2018-04-07 08:44:39 +00:00
}
m_hoveredNodeItem = newHoverNodeItem ;
if ( nullptr ! = m_hoveredNodeItem ) {
2018-04-18 01:49:23 +00:00
hoveredPartId = querySkeletonItemPartId ( m_hoveredNodeItem ) ;
2018-04-21 00:23:27 +00:00
setItemHoveredOnAllProfiles ( m_hoveredNodeItem , true ) ;
2018-04-07 08:44:39 +00:00
}
}
if ( newHoverEdgeItem ! = m_hoveredEdgeItem ) {
if ( nullptr ! = m_hoveredEdgeItem ) {
2018-04-21 00:23:27 +00:00
setItemHoveredOnAllProfiles ( m_hoveredEdgeItem , false ) ;
2018-04-07 08:44:39 +00:00
}
m_hoveredEdgeItem = newHoverEdgeItem ;
if ( nullptr ! = m_hoveredEdgeItem ) {
2018-04-18 01:49:23 +00:00
hoveredPartId = querySkeletonItemPartId ( m_hoveredEdgeItem ) ;
2018-04-21 00:23:27 +00:00
setItemHoveredOnAllProfiles ( m_hoveredEdgeItem , true ) ;
2018-04-07 08:44:39 +00:00
}
}
2018-04-18 01:49:23 +00:00
if ( m_hoveredNodeItem ) {
hoveredPartId = querySkeletonItemPartId ( m_hoveredNodeItem ) ;
} else if ( m_hoveredEdgeItem ) {
hoveredPartId = querySkeletonItemPartId ( m_hoveredEdgeItem ) ;
}
hoverPart ( hoveredPartId ) ;
2018-04-07 08:44:39 +00:00
}
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
if ( Document : : EditMode : : Add = = m_document - > editMode ) {
2018-04-07 08:44:39 +00:00
QPointF mouseScenePos = mouseEventScenePos ( event ) ;
m_cursorNodeItem - > setOrigin ( mouseScenePos ) ;
2018-04-08 15:08:23 +00:00
if ( m_addFromNodeItem ) {
m_cursorEdgeItem - > setEndpoints ( m_addFromNodeItem , m_cursorNodeItem ) ;
2019-10-21 12:21:57 +00:00
if ( ! m_cursorNodeItem - > isVisible ( ) )
m_cursorNodeItem - > setRadius ( m_addFromNodeItem - > radius ( ) ) ;
2018-04-07 08:44:39 +00:00
if ( ! m_cursorEdgeItem - > isVisible ( ) ) {
m_cursorEdgeItem - > show ( ) ;
}
}
2019-10-21 12:21:57 +00:00
if ( ! m_cursorNodeItem - > isVisible ( ) ) {
m_cursorNodeItem - > show ( ) ;
}
2018-04-07 08:44:39 +00:00
return true ;
}
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
if ( Document : : EditMode : : Select = = m_document - > editMode ) {
2018-04-15 12:11:51 +00:00
if ( m_moveStarted ) {
if ( m_checkedOriginItem ) {
QPointF mouseScenePos = mouseEventScenePos ( event ) ;
float byX = mouseScenePos . x ( ) - m_lastScenePos . x ( ) ;
float byY = mouseScenePos . y ( ) - m_lastScenePos . y ( ) ;
moveCheckedOrigin ( byX , byY ) ;
m_lastScenePos = mouseScenePos ;
m_moveHappened = true ;
return true ;
} else if ( ! m_rangeSelectionSet . empty ( ) ) {
QPointF mouseScenePos = mouseEventScenePos ( event ) ;
float byX = mouseScenePos . x ( ) - m_lastScenePos . x ( ) ;
float byY = mouseScenePos . y ( ) - m_lastScenePos . y ( ) ;
if ( QGuiApplication : : queryKeyboardModifiers ( ) . testFlag ( Qt : : ShiftModifier ) ) {
2022-10-18 09:35:04 +00:00
std : : set < SkeletonGraphicsNodeItem * > nodeItems ;
2018-05-24 01:44:40 +00:00
readMergedSkeletonNodeSetFromRangeSelection ( & nodeItems ) ;
2018-06-29 06:55:32 +00:00
bool ikMoved = false ;
2018-05-24 01:44:40 +00:00
if ( nodeItems . size ( ) = = 1 ) {
2022-10-18 09:35:04 +00:00
auto & nodeItem = * nodeItems . begin ( ) ;
2022-11-07 09:41:43 +00:00
const Document : : Node * node = m_document - > findNode ( nodeItem - > id ( ) ) ;
2018-05-24 01:44:40 +00:00
if ( node - > edgeIds . size ( ) = = 1 ) {
const auto origin = nodeItem - > origin ( ) ;
byX = mouseScenePos . x ( ) - origin . x ( ) ;
byY = mouseScenePos . y ( ) - origin . y ( ) ;
byX = sceneRadiusToUnified ( byX ) ;
byY = sceneRadiusToUnified ( byY ) ;
2019-10-19 13:14:36 +00:00
QVector3D target = QVector3D ( node - > getX ( m_rotated ) , node - > getY ( m_rotated ) , node - > getZ ( m_rotated ) ) ;
2022-11-07 09:41:43 +00:00
if ( Document : : Profile : : Main = = nodeItem - > profile ( ) ) {
2018-05-24 01:44:40 +00:00
target . setX ( target . x ( ) + byX ) ;
target . setY ( target . y ( ) + byY ) ;
} else {
target . setY ( target . y ( ) + byY ) ;
target . setZ ( target . z ( ) + byX ) ;
}
emit ikMove ( nodeItem - > id ( ) , target ) ;
2018-06-29 06:55:32 +00:00
ikMoved = true ;
2018-05-24 01:44:40 +00:00
}
}
2018-06-29 06:55:32 +00:00
if ( ! ikMoved )
rotateSelected ( byX ) ;
2018-04-15 12:11:51 +00:00
} else {
moveSelected ( byX , byY ) ;
}
m_lastScenePos = mouseScenePos ;
m_moveHappened = true ;
return true ;
2018-04-07 08:44:39 +00:00
}
}
}
2022-10-18 09:35:04 +00:00
2018-04-07 08:44:39 +00:00
return false ;
}
2018-04-13 01:27:28 +00:00
void SkeletonGraphicsWidget : : rotateSelected ( int degree )
{
if ( m_rangeSelectionSet . empty ( ) )
return ;
2022-10-18 09:35:04 +00:00
std : : set < SkeletonGraphicsNodeItem * > nodeItems ;
2018-04-13 01:27:28 +00:00
readMergedSkeletonNodeSetFromRangeSelection ( & nodeItems ) ;
2022-10-18 09:35:04 +00:00
2018-06-29 06:55:32 +00:00
QVector2D center ;
2018-09-03 07:05:05 +00:00
2018-06-29 06:55:32 +00:00
if ( 1 = = nodeItems . size ( ) & & m_document - > originSettled ( ) ) {
// Rotate all children nodes around this node
// 1. Pick who is the parent from neighbors
// 2. Rotate all the remaining neighbor nodes and their children exlucde the picked parent
2019-10-19 13:14:36 +00:00
QVector3D worldOrigin = QVector3D ( m_document - > getOriginX ( m_rotated ) , m_document - > getOriginY ( m_rotated ) , m_document - > getOriginZ ( m_rotated ) ) ;
2022-10-18 09:35:04 +00:00
SkeletonGraphicsNodeItem * centerNodeItem = * nodeItems . begin ( ) ;
const auto & centerNode = m_document - > findNode ( centerNodeItem - > id ( ) ) ;
2018-06-29 06:55:32 +00:00
if ( nullptr = = centerNode ) {
qDebug ( ) < < " findNode: " < < centerNodeItem - > id ( ) < < " failed while rotate " ;
return ;
}
2021-11-18 14:58:01 +00:00
std : : vector < std : : pair < dust3d : : Uuid , float > > directNeighborDists ;
2022-10-18 09:35:04 +00:00
for ( const auto & neighborId : centerNode - > edgeIds ) {
const auto & neighborEdge = m_document - > findEdge ( neighborId ) ;
2018-06-29 06:55:32 +00:00
if ( nullptr = = neighborEdge ) {
qDebug ( ) < < " findEdge: " < < neighborId < < " failed while rotate " ;
continue ;
}
2022-10-18 09:35:04 +00:00
const auto & neighborNodeId = neighborEdge - > neighborOf ( centerNodeItem - > id ( ) ) ;
const auto & neighborNode = m_document - > findNode ( neighborNodeId ) ;
2018-06-29 06:55:32 +00:00
if ( nullptr = = centerNode ) {
qDebug ( ) < < " findNode: " < < neighborNodeId < < " failed while rotate " ;
continue ;
}
2019-10-19 13:14:36 +00:00
QVector3D nodeOrigin ( neighborNode - > getX ( m_rotated ) , neighborNode - > getY ( m_rotated ) , neighborNode - > getZ ( m_rotated ) ) ;
2018-06-29 06:55:32 +00:00
directNeighborDists . push_back ( std : : make_pair ( neighborNodeId , ( nodeOrigin - worldOrigin ) . lengthSquared ( ) ) ) ;
}
2022-10-18 09:35:04 +00:00
std : : sort ( directNeighborDists . begin ( ) , directNeighborDists . end ( ) , [ ] ( const std : : pair < dust3d : : Uuid , float > & a , const std : : pair < dust3d : : Uuid , float > & b ) {
2018-06-29 06:55:32 +00:00
return a . second < b . second ;
} ) ;
int skippedNum = 1 ;
if ( directNeighborDists . size ( ) = = 1 ) {
skippedNum = 0 ;
}
2021-11-18 14:58:01 +00:00
std : : set < dust3d : : Uuid > neighborIds ;
2018-06-29 06:55:32 +00:00
// Adding self to force the neighbor finding not reverse
neighborIds . insert ( centerNodeItem - > id ( ) ) ;
for ( int i = skippedNum ; i < ( int ) directNeighborDists . size ( ) ; i + + ) {
neighborIds . insert ( directNeighborDists [ i ] . first ) ;
m_document - > findAllNeighbors ( directNeighborDists [ i ] . first , neighborIds ) ;
}
center = QVector2D ( centerNodeItem - > origin ( ) . x ( ) , centerNodeItem - > origin ( ) . y ( ) ) ;
nodeItems . clear ( ) ;
2022-10-18 09:35:04 +00:00
for ( const auto & neighborId : neighborIds ) {
const auto & findItemResult = nodeItemMap . find ( neighborId ) ;
2018-06-29 06:55:32 +00:00
if ( findItemResult = = nodeItemMap . end ( ) ) {
qDebug ( ) < < " find node item: " < < neighborId < < " failed " ;
continue ;
}
2022-11-07 09:41:43 +00:00
if ( Document : : Profile : : Main = = centerNodeItem - > profile ( ) ) {
2018-06-29 06:55:32 +00:00
nodeItems . insert ( findItemResult - > second . first ) ;
} else {
nodeItems . insert ( findItemResult - > second . second ) ;
}
}
} else {
center = centerOfNodeItemSet ( nodeItems ) ;
}
2018-09-03 07:05:05 +00:00
rotateItems ( nodeItems , degree , center ) ;
}
2022-10-18 09:35:04 +00:00
void SkeletonGraphicsWidget : : rotateItems ( const std : : set < SkeletonGraphicsNodeItem * > & nodeItems , int degree , QVector2D center )
2018-09-03 07:05:05 +00:00
{
emit disableAllPositionRelatedLocks ( ) ;
QVector3D centerPoint ( center . x ( ) , center . y ( ) , 0 ) ;
2022-10-18 09:35:04 +00:00
for ( const auto & it : nodeItems ) {
SkeletonGraphicsNodeItem * nodeItem = it ;
2018-04-13 01:27:28 +00:00
QMatrix4x4 mat ;
QPointF nodeOrigin = nodeItem - > origin ( ) ;
QVector3D nodeOriginPoint ( nodeOrigin . x ( ) , nodeOrigin . y ( ) , 0 ) ;
QVector3D p = nodeOriginPoint - centerPoint ;
mat . rotate ( degree , 0 , 0 , 1 ) ;
p = mat * p ;
QVector3D finalPoint = p + centerPoint ;
float byX = sceneRadiusToUnified ( finalPoint . x ( ) - nodeOrigin . x ( ) ) ;
float byY = sceneRadiusToUnified ( finalPoint . y ( ) - nodeOrigin . y ( ) ) ;
2022-11-07 09:41:43 +00:00
if ( Document : : Profile : : Main = = nodeItem - > profile ( ) ) {
2019-10-19 13:14:36 +00:00
if ( m_rotated )
emit moveNodeBy ( nodeItem - > id ( ) , byY , byX , 0 ) ;
else
emit moveNodeBy ( nodeItem - > id ( ) , byX , byY , 0 ) ;
2018-04-13 01:27:28 +00:00
} else {
2019-10-19 13:14:36 +00:00
if ( m_rotated )
emit moveNodeBy ( nodeItem - > id ( ) , byY , 0 , byX ) ;
else
emit moveNodeBy ( nodeItem - > id ( ) , 0 , byY , byX ) ;
2018-04-13 01:27:28 +00:00
}
}
2018-09-03 07:05:05 +00:00
emit enableAllPositionRelatedLocks ( ) ;
}
void SkeletonGraphicsWidget : : rotateAllSideProfile ( int degree )
{
2022-10-18 09:35:04 +00:00
std : : set < SkeletonGraphicsNodeItem * > items ;
for ( const auto & item : nodeItemMap ) {
2018-09-03 07:05:05 +00:00
items . insert ( item . second . second ) ;
}
2019-10-19 13:14:36 +00:00
QVector2D center ( scenePosFromUnified ( QPointF ( m_document - > getOriginZ ( m_rotated ) , m_document - > getOriginY ( m_rotated ) ) ) ) ;
2018-09-03 07:05:05 +00:00
rotateItems ( items , degree , center ) ;
2018-04-13 01:27:28 +00:00
}
2018-04-15 12:11:51 +00:00
void SkeletonGraphicsWidget : : moveCheckedOrigin ( float byX , float byY )
{
if ( ! m_checkedOriginItem )
return ;
byX = sceneRadiusToUnified ( byX ) ;
byY = sceneRadiusToUnified ( byY ) ;
2022-11-07 09:41:43 +00:00
if ( Document : : Profile : : Main = = m_checkedOriginItem - > profile ( ) ) {
2019-10-19 13:14:36 +00:00
if ( m_rotated )
emit moveOriginBy ( byY , byX , 0 ) ;
else
emit moveOriginBy ( byX , byY , 0 ) ;
2018-04-15 12:11:51 +00:00
} else {
2019-10-19 13:14:36 +00:00
if ( m_rotated )
emit moveOriginBy ( byY , 0 , byX ) ;
else
emit moveOriginBy ( 0 , byY , byX ) ;
2018-04-15 12:11:51 +00:00
}
}
2018-04-13 01:27:28 +00:00
void SkeletonGraphicsWidget : : moveSelected ( float byX , float byY )
{
if ( m_rangeSelectionSet . empty ( ) )
return ;
2022-10-18 09:35:04 +00:00
2021-11-18 14:58:01 +00:00
m_ikMoveEndEffectorId = dust3d : : Uuid ( ) ;
2022-10-18 09:35:04 +00:00
2018-04-13 01:27:28 +00:00
byX = sceneRadiusToUnified ( byX ) ;
byY = sceneRadiusToUnified ( byY ) ;
2022-10-18 09:35:04 +00:00
std : : set < SkeletonGraphicsNodeItem * > nodeItems ;
2018-04-13 01:27:28 +00:00
readMergedSkeletonNodeSetFromRangeSelection ( & nodeItems ) ;
2022-10-18 09:35:04 +00:00
for ( const auto & it : nodeItems ) {
SkeletonGraphicsNodeItem * nodeItem = it ;
2022-11-07 09:41:43 +00:00
if ( Document : : Profile : : Main = = nodeItem - > profile ( ) ) {
2019-10-19 13:14:36 +00:00
if ( m_rotated )
emit moveNodeBy ( nodeItem - > id ( ) , byY , byX , 0 ) ;
else
emit moveNodeBy ( nodeItem - > id ( ) , byX , byY , 0 ) ;
2018-04-13 01:27:28 +00:00
} else {
2019-10-19 13:14:36 +00:00
if ( m_rotated )
emit moveNodeBy ( nodeItem - > id ( ) , byY , 0 , byX ) ;
else
emit moveNodeBy ( nodeItem - > id ( ) , 0 , byY , byX ) ;
2018-04-13 01:27:28 +00:00
}
}
}
2018-06-21 08:24:18 +00:00
void SkeletonGraphicsWidget : : switchSelectedXZ ( )
{
if ( m_rangeSelectionSet . empty ( ) )
return ;
2022-10-18 09:35:04 +00:00
2021-11-18 14:58:01 +00:00
std : : set < dust3d : : Uuid > nodeIdSet ;
2018-06-21 08:24:18 +00:00
readSkeletonNodeAndEdgeIdSetFromRangeSelection ( & nodeIdSet ) ;
if ( nodeIdSet . empty ( ) )
return ;
2022-10-18 09:35:04 +00:00
2018-06-21 08:24:18 +00:00
emit batchChangeBegin ( ) ;
2022-10-18 09:35:04 +00:00
for ( const auto nodeId : nodeIdSet ) {
2018-06-21 08:24:18 +00:00
emit switchNodeXZ ( nodeId ) ;
}
emit batchChangeEnd ( ) ;
emit groupOperationAdded ( ) ;
}
2018-04-13 01:27:28 +00:00
void SkeletonGraphicsWidget : : zoomSelected ( float delta )
{
if ( m_rangeSelectionSet . empty ( ) )
return ;
2022-10-18 09:35:04 +00:00
std : : set < SkeletonGraphicsNodeItem * > nodeItems ;
2018-04-13 01:27:28 +00:00
readMergedSkeletonNodeSetFromRangeSelection ( & nodeItems ) ;
2022-10-18 09:35:04 +00:00
2018-04-13 01:27:28 +00:00
float unifiedDelta = sceneRadiusToUnified ( delta ) ;
2022-10-18 09:35:04 +00:00
for ( const auto & it : nodeItems ) {
SkeletonGraphicsNodeItem * nodeItem = it ;
2018-04-13 01:27:28 +00:00
emit scaleNodeByAddRadius ( nodeItem - > id ( ) , unifiedDelta ) ;
}
}
2022-10-18 09:35:04 +00:00
void SkeletonGraphicsWidget : : getOtherProfileNodeItems ( const std : : set < SkeletonGraphicsNodeItem * > & nodeItemSet ,
std : : set < SkeletonGraphicsNodeItem * > * otherProfileNodeItemSet )
2019-06-09 04:58:09 +00:00
{
2022-10-18 09:35:04 +00:00
for ( const auto & nodeItem : nodeItemSet ) {
2019-06-09 04:58:09 +00:00
auto findNodeItem = nodeItemMap . find ( nodeItem - > id ( ) ) ;
if ( findNodeItem = = nodeItemMap . end ( ) )
continue ;
if ( nodeItem = = findNodeItem - > second . first )
otherProfileNodeItemSet - > insert ( findNodeItem - > second . second ) ;
else
otherProfileNodeItemSet - > insert ( findNodeItem - > second . first ) ;
}
}
2018-04-13 01:27:28 +00:00
void SkeletonGraphicsWidget : : scaleSelected ( float delta )
{
if ( m_rangeSelectionSet . empty ( ) )
return ;
2022-10-18 09:35:04 +00:00
std : : set < SkeletonGraphicsNodeItem * > nodeItems ;
2018-04-13 01:27:28 +00:00
readMergedSkeletonNodeSetFromRangeSelection ( & nodeItems ) ;
2022-10-18 09:35:04 +00:00
std : : set < SkeletonGraphicsNodeItem * > otherProfileNodeItems ;
2019-06-09 04:58:09 +00:00
getOtherProfileNodeItems ( nodeItems , & otherProfileNodeItems ) ;
2022-10-18 09:35:04 +00:00
2018-04-13 01:27:28 +00:00
QVector2D center = centerOfNodeItemSet ( nodeItems ) ;
2019-06-09 04:58:09 +00:00
QVector2D otherCenter = centerOfNodeItemSet ( otherProfileNodeItems ) ;
2021-11-18 14:58:01 +00:00
std : : map < dust3d : : Uuid , std : : tuple < float , float , float > > moveByMap ;
2019-08-17 11:32:18 +00:00
float scale = sceneRadiusToUnified ( delta ) ;
2022-10-18 09:35:04 +00:00
for ( const auto & nodeItem : nodeItems ) {
2018-04-13 01:27:28 +00:00
QVector2D origin = QVector2D ( nodeItem - > origin ( ) ) ;
2019-06-09 04:58:09 +00:00
QVector2D ray = ( center - origin ) * scale ;
2018-04-13 01:27:28 +00:00
float byX = - sceneRadiusToUnified ( ray . x ( ) ) ;
float byY = - sceneRadiusToUnified ( ray . y ( ) ) ;
2022-11-07 09:41:43 +00:00
if ( Document : : Profile : : Main = = nodeItem - > profile ( ) ) {
2019-06-09 04:58:09 +00:00
moveByMap [ nodeItem - > id ( ) ] = std : : make_tuple ( byX , byY , 0.0 ) ;
2018-04-13 01:27:28 +00:00
} else {
2019-06-09 04:58:09 +00:00
moveByMap [ nodeItem - > id ( ) ] = std : : make_tuple ( 0.0 , byY , byX ) ;
}
}
2022-10-18 09:35:04 +00:00
for ( const auto & nodeItem : otherProfileNodeItems ) {
2019-06-09 04:58:09 +00:00
QVector2D origin = QVector2D ( nodeItem - > origin ( ) ) ;
QVector2D ray = ( otherCenter - origin ) * scale ;
float byX = - sceneRadiusToUnified ( ray . x ( ) ) ;
2022-11-07 09:41:43 +00:00
if ( Document : : Profile : : Main = = nodeItem - > profile ( ) ) {
2019-06-09 04:58:09 +00:00
std : : get < 0 > ( moveByMap [ nodeItem - > id ( ) ] ) = byX ;
} else {
std : : get < 2 > ( moveByMap [ nodeItem - > id ( ) ] ) = byX ;
2018-04-13 01:27:28 +00:00
}
}
2022-10-18 09:35:04 +00:00
for ( const auto & it : moveByMap ) {
2019-10-19 13:14:36 +00:00
if ( m_rotated )
emit moveNodeBy ( it . first , std : : get < 1 > ( it . second ) , std : : get < 0 > ( it . second ) , std : : get < 2 > ( it . second ) ) ;
else
emit moveNodeBy ( it . first , std : : get < 0 > ( it . second ) , std : : get < 1 > ( it . second ) , std : : get < 2 > ( it . second ) ) ;
2019-06-09 04:58:09 +00:00
}
2018-04-13 01:27:28 +00:00
}
2022-10-18 09:35:04 +00:00
bool SkeletonGraphicsWidget : : wheel ( QWheelEvent * event )
2018-04-07 08:44:39 +00:00
{
2019-08-17 11:32:18 +00:00
float delta = 0 ;
if ( event - > delta ( ) > 0 )
delta = 1 ;
else
delta = - 1 ;
2022-11-07 09:41:43 +00:00
if ( Document : : EditMode : : Add = = m_document - > editMode ) {
2018-04-07 08:44:39 +00:00
if ( m_cursorNodeItem - > isVisible ( ) ) {
m_cursorNodeItem - > setRadius ( m_cursorNodeItem - > radius ( ) + delta ) ;
return true ;
}
2022-11-07 09:41:43 +00:00
} else if ( Document : : EditMode : : Select = = m_document - > editMode ) {
2018-04-08 15:08:23 +00:00
if ( ! m_rangeSelectionSet . empty ( ) ) {
if ( QGuiApplication : : queryKeyboardModifiers ( ) . testFlag ( Qt : : ControlModifier ) ) {
2018-04-13 01:27:28 +00:00
scaleSelected ( delta ) ;
2018-04-08 15:08:23 +00:00
} else {
2018-04-13 01:27:28 +00:00
zoomSelected ( delta ) ;
2018-04-08 15:08:23 +00:00
}
2018-04-08 23:34:46 +00:00
emit groupOperationAdded ( ) ;
2018-04-07 08:44:39 +00:00
return true ;
2018-04-08 15:08:23 +00:00
} else if ( m_hoveredNodeItem ) {
float unifiedDelta = sceneRadiusToUnified ( delta ) ;
emit scaleNodeByAddRadius ( m_hoveredNodeItem - > id ( ) , unifiedDelta ) ;
2018-04-08 23:34:46 +00:00
emit groupOperationAdded ( ) ;
2018-04-07 08:44:39 +00:00
return true ;
}
}
return false ;
}
2022-10-18 09:35:04 +00:00
QVector2D SkeletonGraphicsWidget : : centerOfNodeItemSet ( const std : : set < SkeletonGraphicsNodeItem * > & set )
2018-04-09 14:24:30 +00:00
{
QVector2D center ;
2022-10-18 09:35:04 +00:00
for ( const auto & nodeItem : set ) {
2018-04-09 14:24:30 +00:00
center + = QVector2D ( nodeItem - > origin ( ) ) ;
}
center / = set . size ( ) ;
return center ;
}
void SkeletonGraphicsWidget : : flipHorizontally ( )
{
2022-10-18 09:35:04 +00:00
std : : set < SkeletonGraphicsNodeItem * > nodeItems ;
2018-04-09 14:24:30 +00:00
readMergedSkeletonNodeSetFromRangeSelection ( & nodeItems ) ;
if ( nodeItems . empty ( ) )
return ;
QVector2D center = centerOfNodeItemSet ( nodeItems ) ;
2018-06-15 09:58:46 +00:00
emit batchChangeBegin ( ) ;
2022-10-18 09:35:04 +00:00
for ( const auto & nodeItem : nodeItems ) {
2018-04-09 14:24:30 +00:00
QPointF origin = nodeItem - > origin ( ) ;
float offset = origin . x ( ) - center . x ( ) ;
float unifiedOffset = - sceneRadiusToUnified ( offset * 2 ) ;
2022-11-07 09:41:43 +00:00
if ( Document : : Profile : : Main = = nodeItem - > profile ( ) ) {
2019-10-19 13:14:36 +00:00
if ( m_rotated )
emit moveNodeBy ( nodeItem - > id ( ) , 0 , unifiedOffset , 0 ) ;
else
emit moveNodeBy ( nodeItem - > id ( ) , unifiedOffset , 0 , 0 ) ;
2018-04-09 14:24:30 +00:00
} else {
emit moveNodeBy ( nodeItem - > id ( ) , 0 , 0 , unifiedOffset ) ;
}
}
2018-06-15 09:58:46 +00:00
emit batchChangeEnd ( ) ;
emit groupOperationAdded ( ) ;
2018-04-09 14:24:30 +00:00
}
void SkeletonGraphicsWidget : : flipVertically ( )
{
2022-10-18 09:35:04 +00:00
std : : set < SkeletonGraphicsNodeItem * > nodeItems ;
2018-04-09 14:24:30 +00:00
readMergedSkeletonNodeSetFromRangeSelection ( & nodeItems ) ;
if ( nodeItems . empty ( ) )
return ;
QVector2D center = centerOfNodeItemSet ( nodeItems ) ;
2018-06-15 09:58:46 +00:00
emit batchChangeBegin ( ) ;
2022-10-18 09:35:04 +00:00
for ( const auto & nodeItem : nodeItems ) {
2018-04-09 14:24:30 +00:00
QPointF origin = nodeItem - > origin ( ) ;
float offset = origin . y ( ) - center . y ( ) ;
float unifiedOffset = - sceneRadiusToUnified ( offset * 2 ) ;
2019-10-19 13:14:36 +00:00
if ( m_rotated )
emit moveNodeBy ( nodeItem - > id ( ) , unifiedOffset , 0 , 0 ) ;
else
emit moveNodeBy ( nodeItem - > id ( ) , 0 , unifiedOffset , 0 ) ;
2018-04-09 14:24:30 +00:00
}
2018-06-15 09:58:46 +00:00
emit batchChangeEnd ( ) ;
emit groupOperationAdded ( ) ;
}
void SkeletonGraphicsWidget : : rotateClockwise90Degree ( )
{
emit batchChangeBegin ( ) ;
emit rotateSelected ( 90 ) ;
emit batchChangeEnd ( ) ;
emit groupOperationAdded ( ) ;
}
void SkeletonGraphicsWidget : : rotateCounterclockwise90Degree ( )
{
emit batchChangeBegin ( ) ;
emit rotateSelected ( 360 - 90 ) ;
emit batchChangeEnd ( ) ;
emit groupOperationAdded ( ) ;
2018-04-09 14:24:30 +00:00
}
2018-09-03 07:05:05 +00:00
void SkeletonGraphicsWidget : : rotateAllMainProfileClockwise90DegreeAlongOrigin ( )
{
if ( ! m_document - > originSettled ( ) )
return ;
emit batchChangeBegin ( ) ;
emit rotateAllSideProfile ( 90 ) ;
emit batchChangeEnd ( ) ;
emit groupOperationAdded ( ) ;
}
void SkeletonGraphicsWidget : : rotateAllMainProfileCounterclockwise90DegreeAlongOrigin ( )
{
if ( ! m_document - > originSettled ( ) )
return ;
emit batchChangeBegin ( ) ;
emit rotateAllSideProfile ( 360 - 90 ) ;
emit batchChangeEnd ( ) ;
emit groupOperationAdded ( ) ;
}
2022-10-18 09:35:04 +00:00
bool SkeletonGraphicsWidget : : mouseRelease ( QMouseEvent * event )
2018-04-07 08:44:39 +00:00
{
if ( event - > button ( ) = = Qt : : LeftButton ) {
2020-12-17 11:54:11 +00:00
bool processed = m_dragStarted | | m_moveStarted | | m_rangeSelectionStarted ;
2018-04-07 08:44:39 +00:00
if ( m_dragStarted ) {
m_dragStarted = false ;
updateCursor ( ) ;
}
if ( m_moveStarted ) {
m_moveStarted = false ;
2018-04-13 00:04:18 +00:00
m_lastRot = 0 ;
2018-04-09 00:32:02 +00:00
if ( m_moveHappened )
emit groupOperationAdded ( ) ;
2018-04-07 08:44:39 +00:00
}
2018-04-08 15:08:23 +00:00
if ( m_rangeSelectionStarted ) {
m_selectionItem - > hide ( ) ;
m_rangeSelectionStarted = false ;
}
2018-04-07 08:44:39 +00:00
return processed ;
}
return false ;
}
2022-10-18 09:35:04 +00:00
QPointF SkeletonGraphicsWidget : : mouseEventScenePos ( QMouseEvent * event )
2018-04-07 08:44:39 +00:00
{
return mapToScene ( mapFromGlobal ( event - > globalPos ( ) ) ) ;
}
2022-10-18 09:35:04 +00:00
bool SkeletonGraphicsWidget : : mousePress ( QMouseEvent * event )
2018-04-07 08:44:39 +00:00
{
if ( event - > button ( ) = = Qt : : LeftButton ) {
2022-11-07 09:41:43 +00:00
if ( Document : : EditMode : : ZoomIn = = m_document - > editMode ) {
2018-04-07 08:44:39 +00:00
ViewportAnchor lastAnchor = transformationAnchor ( ) ;
2018-04-08 15:08:23 +00:00
setTransformationAnchor ( QGraphicsView : : AnchorUnderMouse ) ;
2020-10-14 13:25:30 +00:00
scale ( 1.25 , 1.25 ) ;
2018-04-07 08:44:39 +00:00
setTransformationAnchor ( lastAnchor ) ;
return true ;
2022-11-07 09:41:43 +00:00
} else if ( Document : : EditMode : : ZoomOut = = m_document - > editMode ) {
2018-04-07 08:44:39 +00:00
ViewportAnchor lastAnchor = transformationAnchor ( ) ;
2018-04-08 15:08:23 +00:00
setTransformationAnchor ( QGraphicsView : : AnchorUnderMouse ) ;
2020-10-14 13:25:30 +00:00
scale ( 0.8 , 0.8 ) ;
2018-04-07 08:44:39 +00:00
setTransformationAnchor ( lastAnchor ) ;
2020-10-14 13:25:30 +00:00
//if ((!verticalScrollBar() || !verticalScrollBar()->isVisible()) &&
// (!horizontalScrollBar() || !horizontalScrollBar()->isVisible())) {
// setTransform(QTransform());
//}
2018-04-07 08:44:39 +00:00
return true ;
2022-11-07 09:41:43 +00:00
} else if ( Document : : EditMode : : Drag = = m_document - > editMode ) {
2018-04-07 08:44:39 +00:00
if ( ! m_dragStarted ) {
m_lastGlobalPos = event - > globalPos ( ) ;
m_dragStarted = true ;
updateCursor ( ) ;
}
2022-11-07 09:41:43 +00:00
} else if ( Document : : EditMode : : Add = = m_document - > editMode ) {
2018-04-07 08:44:39 +00:00
if ( m_cursorNodeItem - > isVisible ( ) ) {
2018-04-08 15:08:23 +00:00
if ( m_addFromNodeItem ) {
2022-10-18 09:35:04 +00:00
if ( m_hoveredNodeItem & & m_addFromNodeItem & & m_hoveredNodeItem ! = m_addFromNodeItem & & m_hoveredNodeItem - > profile ( ) = = m_addFromNodeItem - > profile ( ) & & ! m_document - > findEdgeByNodes ( m_addFromNodeItem - > id ( ) , m_hoveredNodeItem - > id ( ) ) & & m_document - > isNodeEditable ( m_hoveredNodeItem - > id ( ) ) ) {
2019-06-26 11:35:56 +00:00
if ( m_document - > isNodeConnectable ( m_hoveredNodeItem - > id ( ) ) ) {
emit addEdge ( m_addFromNodeItem - > id ( ) , m_hoveredNodeItem - > id ( ) ) ;
emit groupOperationAdded ( ) ;
2022-11-07 09:41:43 +00:00
emit setEditMode ( Document : : EditMode : : Select ) ;
2019-06-26 11:35:56 +00:00
return true ;
}
2018-04-07 08:44:39 +00:00
}
}
QPointF mainProfile = m_cursorNodeItem - > origin ( ) ;
QPointF sideProfile = mainProfile ;
2018-04-08 15:08:23 +00:00
if ( m_addFromNodeItem ) {
auto itemIt = nodeItemMap . find ( m_addFromNodeItem - > id ( ) ) ;
2022-11-07 09:41:43 +00:00
if ( Document : : Profile : : Main = = m_addFromNodeItem - > profile ( ) )
2018-04-10 08:44:02 +00:00
sideProfile . setX ( itemIt - > second . second - > origin ( ) . x ( ) ) ;
else
mainProfile . setX ( itemIt - > second . first - > origin ( ) . x ( ) ) ;
2018-04-07 08:44:39 +00:00
} else {
2018-04-08 01:30:55 +00:00
if ( mainProfile . x ( ) > = scene ( ) - > width ( ) / 2 ) {
sideProfile . setX ( mainProfile . x ( ) - scene ( ) - > width ( ) / 4 ) ;
} else {
2022-10-18 09:35:04 +00:00
sideProfile . setX ( mainProfile . x ( ) + scene ( ) - > width ( ) / 4 ) ;
2018-04-08 01:30:55 +00:00
}
2018-04-07 08:44:39 +00:00
}
QPointF unifiedMainPos = scenePosToUnified ( mainProfile ) ;
QPointF unifiedSidePos = scenePosToUnified ( sideProfile ) ;
if ( isFloatEqual ( m_lastAddedX , unifiedMainPos . x ( ) ) & & isFloatEqual ( m_lastAddedY , unifiedMainPos . y ( ) ) & & isFloatEqual ( m_lastAddedZ , unifiedSidePos . x ( ) ) )
return true ;
m_lastAddedX = unifiedMainPos . x ( ) ;
m_lastAddedY = unifiedMainPos . y ( ) ;
m_lastAddedZ = unifiedSidePos . x ( ) ;
2019-10-19 13:14:36 +00:00
if ( m_rotated )
2021-11-18 14:58:01 +00:00
emit addNode ( unifiedMainPos . y ( ) , unifiedMainPos . x ( ) , unifiedSidePos . x ( ) , sceneRadiusToUnified ( m_cursorNodeItem - > radius ( ) ) , nullptr = = m_addFromNodeItem ? dust3d : : Uuid ( ) : m_addFromNodeItem - > id ( ) ) ;
2019-10-19 13:14:36 +00:00
else
2021-11-18 14:58:01 +00:00
emit addNode ( unifiedMainPos . x ( ) , unifiedMainPos . y ( ) , unifiedSidePos . x ( ) , sceneRadiusToUnified ( m_cursorNodeItem - > radius ( ) ) , nullptr = = m_addFromNodeItem ? dust3d : : Uuid ( ) : m_addFromNodeItem - > id ( ) ) ;
2018-04-08 23:34:46 +00:00
emit groupOperationAdded ( ) ;
2018-04-07 08:44:39 +00:00
return true ;
}
2022-11-07 09:41:43 +00:00
} else if ( Document : : EditMode : : Select = = m_document - > editMode ) {
2018-04-15 12:11:51 +00:00
bool processed = false ;
if ( m_hoveredOriginItem ! = m_checkedOriginItem ) {
if ( m_checkedOriginItem ) {
m_checkedOriginItem - > setChecked ( false ) ;
m_checkedOriginItem - > setHovered ( false ) ;
}
m_checkedOriginItem = m_hoveredOriginItem ;
if ( m_checkedOriginItem ) {
m_checkedOriginItem - > setChecked ( true ) ;
}
}
if ( m_checkedOriginItem ) {
if ( ! m_moveStarted ) {
m_moveStarted = true ;
m_lastScenePos = mouseEventScenePos ( event ) ;
m_moveHappened = false ;
processed = true ;
}
} else {
2022-10-18 09:35:04 +00:00
if ( ( nullptr = = m_hoveredNodeItem | | m_rangeSelectionSet . find ( m_hoveredNodeItem ) = = m_rangeSelectionSet . end ( ) ) & & ( nullptr = = m_hoveredEdgeItem | | m_rangeSelectionSet . find ( m_hoveredEdgeItem ) = = m_rangeSelectionSet . end ( ) ) ) {
2018-04-08 15:08:23 +00:00
if ( ! QGuiApplication : : queryKeyboardModifiers ( ) . testFlag ( Qt : : ControlModifier ) ) {
clearRangeSelection ( ) ;
}
2018-04-12 14:35:50 +00:00
if ( ! QGuiApplication : : queryKeyboardModifiers ( ) . testFlag ( Qt : : AltModifier ) ) {
2018-04-12 13:24:51 +00:00
if ( m_hoveredNodeItem ) {
addItemToRangeSelection ( m_hoveredNodeItem ) ;
} else if ( m_hoveredEdgeItem ) {
addItemToRangeSelection ( m_hoveredEdgeItem ) ;
}
2018-04-07 08:44:39 +00:00
}
2018-04-12 14:35:50 +00:00
}
if ( QGuiApplication : : queryKeyboardModifiers ( ) . testFlag ( Qt : : AltModifier ) ) {
if ( m_hoveredNodeItem ) {
removeItemFromRangeSelection ( m_hoveredNodeItem ) ;
} else if ( m_hoveredEdgeItem ) {
removeItemFromRangeSelection ( m_hoveredEdgeItem ) ;
}
}
2018-04-08 15:08:23 +00:00
if ( ! m_rangeSelectionSet . empty ( ) ) {
if ( ! QGuiApplication : : queryKeyboardModifiers ( ) . testFlag ( Qt : : ControlModifier ) ) {
2018-04-09 00:32:02 +00:00
if ( ! m_moveStarted ) {
m_moveStarted = true ;
m_lastScenePos = mouseEventScenePos ( event ) ;
m_moveHappened = false ;
processed = true ;
}
2018-04-07 08:44:39 +00:00
}
}
2018-04-15 12:11:51 +00:00
}
if ( processed ) {
return true ;
}
2018-04-07 08:44:39 +00:00
}
}
2022-10-18 09:35:04 +00:00
2018-04-11 15:06:30 +00:00
if ( event - > button ( ) = = Qt : : LeftButton ) {
2022-11-07 09:41:43 +00:00
if ( Document : : EditMode : : Select = = m_document - > editMode ) {
2018-04-11 15:06:30 +00:00
if ( ! m_rangeSelectionStarted ) {
m_rangeSelectionStartPos = mouseEventScenePos ( event ) ;
m_rangeSelectionStarted = true ;
}
}
}
2018-04-07 08:44:39 +00:00
return false ;
}
2021-11-18 14:58:01 +00:00
bool SkeletonGraphicsWidget : : isFloatEqual ( float a , float b )
{
return fabs ( a - b ) < = 0.000001 ;
}
2018-04-07 08:44:39 +00:00
float SkeletonGraphicsWidget : : sceneRadiusToUnified ( float radius )
{
if ( 0 = = scene ( ) - > height ( ) )
return 0 ;
return radius / scene ( ) - > height ( ) ;
}
float SkeletonGraphicsWidget : : sceneRadiusFromUnified ( float radius )
{
return radius * scene ( ) - > height ( ) ;
}
QPointF SkeletonGraphicsWidget : : scenePosToUnified ( QPointF pos )
{
if ( 0 = = scene ( ) - > height ( ) )
return QPointF ( 0 , 0 ) ;
return QPointF ( pos . x ( ) / scene ( ) - > height ( ) , pos . y ( ) / scene ( ) - > height ( ) ) ;
}
QPointF SkeletonGraphicsWidget : : scenePosFromUnified ( QPointF pos )
{
return QPointF ( pos . x ( ) * scene ( ) - > height ( ) , pos . y ( ) * scene ( ) - > height ( ) ) ;
}
2022-10-18 09:35:04 +00:00
bool SkeletonGraphicsWidget : : mouseDoubleClick ( QMouseEvent * event )
2018-04-07 08:44:39 +00:00
{
2018-04-09 11:13:34 +00:00
if ( m_hoveredNodeItem | | m_hoveredEdgeItem ) {
2020-12-15 14:28:20 +00:00
selectPartAll ( ) ;
2018-04-09 11:13:34 +00:00
return true ;
}
2018-04-10 07:59:20 +00:00
if ( QGuiApplication : : queryKeyboardModifiers ( ) . testFlag ( Qt : : ControlModifier ) ) {
emit open ( ) ;
return true ;
}
2018-04-07 08:44:39 +00:00
return false ;
}
2018-06-15 11:54:13 +00:00
void SkeletonGraphicsWidget : : timeToRemoveDeferredNodesAndEdges ( )
{
delete m_deferredRemoveTimer ;
m_deferredRemoveTimer = nullptr ;
2022-10-18 09:35:04 +00:00
2018-06-15 11:54:13 +00:00
bool committed = false ;
2022-10-18 09:35:04 +00:00
2018-06-15 11:54:13 +00:00
if ( ! committed & & ! m_deferredRemoveEdgeIds . empty ( ) ) {
2022-10-18 09:35:04 +00:00
const auto & it = m_deferredRemoveEdgeIds . begin ( ) ;
2018-06-15 11:54:13 +00:00
const auto edgeId = * it ;
m_deferredRemoveEdgeIds . erase ( it ) ;
emit removeEdge ( edgeId ) ;
committed = true ;
}
2022-10-18 09:35:04 +00:00
2018-06-15 11:54:13 +00:00
if ( ! committed & & ! m_deferredRemoveNodeIds . empty ( ) ) {
2022-10-18 09:35:04 +00:00
const auto & it = m_deferredRemoveNodeIds . begin ( ) ;
2018-06-15 11:54:13 +00:00
const auto nodeId = * it ;
m_deferredRemoveNodeIds . erase ( it ) ;
emit removeNode ( nodeId ) ;
committed = true ;
}
2022-10-18 09:35:04 +00:00
2018-06-15 11:54:13 +00:00
if ( committed ) {
m_deferredRemoveTimer = new QTimer ( this ) ;
connect ( m_deferredRemoveTimer , & QTimer : : timeout , this , & SkeletonGraphicsWidget : : timeToRemoveDeferredNodesAndEdges ) ;
m_deferredRemoveTimer - > start ( 0 ) ;
} else {
emit groupOperationAdded ( ) ;
}
}
2018-04-09 03:39:04 +00:00
void SkeletonGraphicsWidget : : deleteSelected ( )
{
2018-06-15 11:54:13 +00:00
if ( m_rangeSelectionSet . empty ( ) )
return ;
2022-10-18 09:35:04 +00:00
2021-11-18 14:58:01 +00:00
std : : set < dust3d : : Uuid > nodeIdSet ;
std : : set < dust3d : : Uuid > edgeIdSet ;
2018-06-15 11:54:13 +00:00
readSkeletonNodeAndEdgeIdSetFromRangeSelection ( & nodeIdSet , & edgeIdSet ) ;
2022-10-18 09:35:04 +00:00
2021-11-18 14:58:01 +00:00
std : : set < dust3d : : Uuid > partIds ;
2022-10-18 09:35:04 +00:00
for ( const auto & it : nodeIdSet ) {
2022-11-07 09:41:43 +00:00
const Document : : Node * node = m_document - > findNode ( it ) ;
2020-04-12 06:48:24 +00:00
if ( nullptr = = node )
continue ;
partIds . insert ( node - > partId ) ;
}
2022-10-18 09:35:04 +00:00
for ( const auto & it : edgeIdSet ) {
2022-11-07 09:41:43 +00:00
const Document : : Edge * edge = m_document - > findEdge ( it ) ;
2020-04-12 06:48:24 +00:00
if ( nullptr = = edge )
continue ;
partIds . insert ( edge - > partId ) ;
}
2021-11-18 14:58:01 +00:00
std : : set < dust3d : : Uuid > cleanupPartIds ;
2022-10-18 09:35:04 +00:00
for ( const auto & partId : partIds ) {
2022-11-07 09:41:43 +00:00
const Document : : Part * part = m_document - > findPart ( partId ) ;
2020-04-12 06:48:24 +00:00
if ( nullptr ! = part ) {
bool allNodesSelected = true ;
2022-10-18 09:35:04 +00:00
for ( const auto & it : part - > nodeIds ) {
2020-04-12 06:48:24 +00:00
if ( nodeIdSet . find ( it ) = = nodeIdSet . end ( ) ) {
allNodesSelected = false ;
break ;
}
}
if ( allNodesSelected ) {
cleanupPartIds . insert ( partId ) ;
}
}
}
2022-10-18 09:35:04 +00:00
for ( const auto & partId : cleanupPartIds ) {
for ( auto it = nodeIdSet . begin ( ) ; it ! = nodeIdSet . end ( ) ; ) {
2022-11-07 09:41:43 +00:00
const Document : : Node * node = m_document - > findNode ( * it ) ;
2020-04-12 06:48:24 +00:00
if ( nullptr ! = node & & node - > partId = = partId ) {
it = nodeIdSet . erase ( it ) ;
continue ;
}
+ + it ;
}
2022-10-18 09:35:04 +00:00
for ( auto it = edgeIdSet . begin ( ) ; it ! = edgeIdSet . end ( ) ; ) {
2022-11-07 09:41:43 +00:00
const Document : : Edge * edge = m_document - > findEdge ( * it ) ;
2020-04-12 06:48:24 +00:00
if ( nullptr ! = edge & & edge - > partId = = partId ) {
it = edgeIdSet . erase ( it ) ;
continue ;
}
+ + it ;
}
}
2022-10-18 09:35:04 +00:00
for ( const auto & partId : cleanupPartIds ) {
2020-04-12 06:48:24 +00:00
emit removePart ( partId ) ;
}
2022-10-18 09:35:04 +00:00
for ( const auto & it : nodeIdSet ) {
2018-06-15 11:54:13 +00:00
m_deferredRemoveNodeIds . insert ( it ) ;
}
2022-10-18 09:35:04 +00:00
for ( const auto & it : edgeIdSet ) {
2018-06-15 11:54:13 +00:00
m_deferredRemoveEdgeIds . insert ( it ) ;
}
2022-10-18 09:35:04 +00:00
2020-04-12 06:48:24 +00:00
if ( ! nodeIdSet . empty ( ) | | ! edgeIdSet . empty ( ) ) {
if ( nullptr = = m_deferredRemoveTimer ) {
timeToRemoveDeferredNodesAndEdges ( ) ;
}
2018-06-15 11:54:13 +00:00
}
2018-04-09 03:39:04 +00:00
}
2018-10-24 13:44:21 +00:00
void SkeletonGraphicsWidget : : shortcutDelete ( )
2018-04-07 08:44:39 +00:00
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2018-10-24 13:44:21 +00:00
bool processed = false ;
if ( ! m_rangeSelectionSet . empty ( ) ) {
deleteSelected ( ) ;
processed = true ;
}
if ( processed ) {
emit groupOperationAdded ( ) ;
return ;
}
}
void SkeletonGraphicsWidget : : shortcutAddMode ( )
{
2022-11-07 09:41:43 +00:00
if ( Document : : EditMode : : Add = = m_document - > editMode ) {
emit setEditMode ( Document : : EditMode : : Select ) ;
2018-10-24 13:44:21 +00:00
} else {
2022-11-07 09:41:43 +00:00
emit setEditMode ( Document : : EditMode : : Add ) ;
2018-10-24 13:44:21 +00:00
}
}
void SkeletonGraphicsWidget : : shortcutUndo ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2018-10-24 13:44:21 +00:00
emit undo ( ) ;
}
void SkeletonGraphicsWidget : : shortcutRedo ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2018-10-24 13:44:21 +00:00
emit redo ( ) ;
}
void SkeletonGraphicsWidget : : shortcutXlock ( )
{
emit setXlockState ( ! m_document - > xlocked ) ;
}
void SkeletonGraphicsWidget : : shortcutYlock ( )
{
emit setYlockState ( ! m_document - > ylocked ) ;
}
void SkeletonGraphicsWidget : : shortcutZlock ( )
{
emit setZlockState ( ! m_document - > zlocked ) ;
}
void SkeletonGraphicsWidget : : shortcutCut ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2018-10-24 13:44:21 +00:00
cut ( ) ;
}
void SkeletonGraphicsWidget : : shortcutCopy ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2018-10-24 13:44:21 +00:00
copy ( ) ;
}
void SkeletonGraphicsWidget : : shortcutPaste ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2018-10-24 13:44:21 +00:00
emit paste ( ) ;
}
void SkeletonGraphicsWidget : : shortcutSelectMode ( )
{
2022-11-07 09:41:43 +00:00
emit setEditMode ( Document : : EditMode : : Select ) ;
2018-10-24 13:44:21 +00:00
}
2019-08-17 10:13:11 +00:00
void SkeletonGraphicsWidget : : shortcutPaintMode ( )
2018-10-24 13:44:21 +00:00
{
2022-11-07 09:41:43 +00:00
emit setEditMode ( Document : : EditMode : : Paint ) ;
2018-10-24 13:44:21 +00:00
}
void SkeletonGraphicsWidget : : shortcutZoomRenderedModelByMinus10 ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2018-10-24 13:44:21 +00:00
emit zoomRenderedModelBy ( - 10 ) ;
}
void SkeletonGraphicsWidget : : shortcutZoomSelectedByMinus1 ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
if ( Document : : EditMode : : Select = = m_document - > editMode & & hasSelection ( ) ) {
2018-10-24 13:44:21 +00:00
zoomSelected ( - 1 ) ;
emit groupOperationAdded ( ) ;
2022-11-07 09:41:43 +00:00
} else if ( Document : : EditMode : : Add = = m_document - > editMode ) {
2018-12-15 13:41:02 +00:00
if ( m_cursorNodeItem - > isVisible ( ) ) {
m_cursorNodeItem - > setRadius ( m_cursorNodeItem - > radius ( ) + - 1 ) ;
}
2018-10-24 13:44:21 +00:00
}
}
void SkeletonGraphicsWidget : : shortcutZoomRenderedModelBy10 ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2018-10-24 13:44:21 +00:00
emit zoomRenderedModelBy ( 10 ) ;
}
void SkeletonGraphicsWidget : : shortcutZoomSelectedBy1 ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
if ( Document : : EditMode : : Select = = m_document - > editMode & & hasSelection ( ) ) {
2018-10-24 13:44:21 +00:00
zoomSelected ( 1 ) ;
emit groupOperationAdded ( ) ;
2022-11-07 09:41:43 +00:00
} else if ( Document : : EditMode : : Add = = m_document - > editMode ) {
2018-12-15 13:41:02 +00:00
if ( m_cursorNodeItem - > isVisible ( ) ) {
m_cursorNodeItem - > setRadius ( m_cursorNodeItem - > radius ( ) + 1 ) ;
}
2018-10-24 13:44:21 +00:00
}
}
void SkeletonGraphicsWidget : : shortcutRotateSelectedByMinus1 ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
if ( ( Document : : EditMode : : Select = = m_document - > editMode ) & & hasSelection ( ) ) {
2018-10-24 13:44:21 +00:00
rotateSelected ( - 1 ) ;
emit groupOperationAdded ( ) ;
}
}
void SkeletonGraphicsWidget : : shortcutRotateSelectedBy1 ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
if ( ( Document : : EditMode : : Select = = m_document - > editMode ) & & hasSelection ( ) ) {
2018-10-24 13:44:21 +00:00
rotateSelected ( 1 ) ;
emit groupOperationAdded ( ) ;
}
}
void SkeletonGraphicsWidget : : shortcutMoveSelectedToLeft ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
if ( Document : : EditMode : : Select = = m_document - > editMode ) {
2018-10-24 13:44:21 +00:00
if ( m_checkedOriginItem ) {
moveCheckedOrigin ( - 1 , 0 ) ;
2018-04-13 01:27:28 +00:00
emit groupOperationAdded ( ) ;
2018-10-24 13:44:21 +00:00
} else if ( hasSelection ( ) ) {
moveSelected ( - 1 , 0 ) ;
2018-04-13 01:27:28 +00:00
emit groupOperationAdded ( ) ;
}
2018-10-24 13:44:21 +00:00
}
}
void SkeletonGraphicsWidget : : shortcutMoveSelectedToRight ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
if ( Document : : EditMode : : Select = = m_document - > editMode ) {
2018-10-24 13:44:21 +00:00
if ( m_checkedOriginItem ) {
moveCheckedOrigin ( 1 , 0 ) ;
2018-04-13 01:27:28 +00:00
emit groupOperationAdded ( ) ;
2018-10-24 13:44:21 +00:00
} else if ( hasSelection ( ) ) {
moveSelected ( 1 , 0 ) ;
2018-04-18 03:14:48 +00:00
emit groupOperationAdded ( ) ;
}
2018-10-24 13:44:21 +00:00
}
}
void SkeletonGraphicsWidget : : shortcutMoveSelectedToUp ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
if ( Document : : EditMode : : Select = = m_document - > editMode ) {
2018-10-24 13:44:21 +00:00
if ( m_checkedOriginItem ) {
moveCheckedOrigin ( 0 , - 1 ) ;
2018-04-18 03:14:48 +00:00
emit groupOperationAdded ( ) ;
2018-10-24 13:44:21 +00:00
} else if ( hasSelection ( ) ) {
moveSelected ( 0 , - 1 ) ;
2018-04-18 03:14:48 +00:00
emit groupOperationAdded ( ) ;
}
2018-10-24 13:44:21 +00:00
}
}
void SkeletonGraphicsWidget : : shortcutMoveSelectedToDown ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
if ( Document : : EditMode : : Select = = m_document - > editMode ) {
2018-10-24 13:44:21 +00:00
if ( m_checkedOriginItem ) {
moveCheckedOrigin ( 0 , 1 ) ;
2018-04-18 03:14:48 +00:00
emit groupOperationAdded ( ) ;
2018-10-24 13:44:21 +00:00
} else if ( hasSelection ( ) ) {
moveSelected ( 0 , 1 ) ;
2018-04-18 03:14:48 +00:00
emit groupOperationAdded ( ) ;
}
2018-10-24 13:44:21 +00:00
}
}
void SkeletonGraphicsWidget : : shortcutScaleSelectedByMinus1 ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
if ( ( Document : : EditMode : : Select = = m_document - > editMode ) & & hasSelection ( ) ) {
2018-10-24 13:44:21 +00:00
scaleSelected ( - 1 ) ;
emit groupOperationAdded ( ) ;
}
}
void SkeletonGraphicsWidget : : shortcutScaleSelectedBy1 ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
if ( ( Document : : EditMode : : Select = = m_document - > editMode ) & & hasSelection ( ) ) {
2018-10-24 13:44:21 +00:00
scaleSelected ( 1 ) ;
emit groupOperationAdded ( ) ;
}
}
void SkeletonGraphicsWidget : : shortcutSwitchProfileOnSelected ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
if ( ( Document : : EditMode : : Select = = m_document - > editMode ) & & hasSelection ( ) ) {
2018-10-24 13:44:21 +00:00
switchProfileOnRangeSelection ( ) ;
}
}
void SkeletonGraphicsWidget : : shortcutShowOrHideSelectedPart ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
if ( Document : : EditMode : : Select = = m_document - > editMode ) {
2019-10-19 00:31:27 +00:00
if ( ! m_lastCheckedPart . isNull ( ) ) {
2022-11-07 09:41:43 +00:00
const Document : : Part * part = m_document - > findPart ( m_lastCheckedPart ) ;
2019-10-19 00:31:27 +00:00
bool partVisible = part & & part - > visible ;
emit setPartVisibleState ( m_lastCheckedPart , ! partVisible ) ;
emit groupOperationAdded ( ) ;
} else {
emit showOrHideAllComponents ( ) ;
}
2018-10-24 13:44:21 +00:00
}
}
void SkeletonGraphicsWidget : : shortcutEnableOrDisableSelectedPart ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
if ( ( Document : : EditMode : : Select = = m_document - > editMode ) & & ! m_lastCheckedPart . isNull ( ) ) {
const Document : : Part * part = m_document - > findPart ( m_lastCheckedPart ) ;
2018-10-24 13:44:21 +00:00
bool partDisabled = part & & part - > disabled ;
emit setPartDisableState ( m_lastCheckedPart , ! partDisabled ) ;
emit groupOperationAdded ( ) ;
}
}
void SkeletonGraphicsWidget : : shortcutLockOrUnlockSelectedPart ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
if ( ( Document : : EditMode : : Select = = m_document - > editMode ) & & ! m_lastCheckedPart . isNull ( ) ) {
const Document : : Part * part = m_document - > findPart ( m_lastCheckedPart ) ;
2018-10-24 13:44:21 +00:00
bool partLocked = part & & part - > locked ;
emit setPartLockState ( m_lastCheckedPart , ! partLocked ) ;
emit groupOperationAdded ( ) ;
}
}
void SkeletonGraphicsWidget : : shortcutXmirrorOnOrOffSelectedPart ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
if ( ( Document : : EditMode : : Select = = m_document - > editMode ) & & ! m_lastCheckedPart . isNull ( ) ) {
const Document : : Part * part = m_document - > findPart ( m_lastCheckedPart ) ;
2018-10-24 13:44:21 +00:00
bool partXmirrored = part & & part - > xMirrored ;
emit setPartXmirrorState ( m_lastCheckedPart , ! partXmirrored ) ;
emit groupOperationAdded ( ) ;
}
}
void SkeletonGraphicsWidget : : shortcutSubdivedOrNotSelectedPart ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
if ( ( Document : : EditMode : : Select = = m_document - > editMode ) & & ! m_lastCheckedPart . isNull ( ) ) {
const Document : : Part * part = m_document - > findPart ( m_lastCheckedPart ) ;
2018-10-24 13:44:21 +00:00
bool partSubdived = part & & part - > subdived ;
emit setPartSubdivState ( m_lastCheckedPart , ! partSubdived ) ;
emit groupOperationAdded ( ) ;
}
}
2019-10-19 00:46:00 +00:00
void SkeletonGraphicsWidget : : shortcutChamferedOrNotSelectedPart ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
if ( ( Document : : EditMode : : Select = = m_document - > editMode ) & & ! m_lastCheckedPart . isNull ( ) ) {
const Document : : Part * part = m_document - > findPart ( m_lastCheckedPart ) ;
2019-10-19 00:46:00 +00:00
bool partChamfered = part & & part - > chamfered ;
emit setPartChamferState ( m_lastCheckedPart , ! partChamfered ) ;
emit groupOperationAdded ( ) ;
}
}
2019-10-25 14:11:17 +00:00
void SkeletonGraphicsWidget : : shortcutSelectAll ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2019-10-25 14:11:17 +00:00
selectAll ( ) ;
}
2018-10-24 13:44:21 +00:00
void SkeletonGraphicsWidget : : shortcutRoundEndOrNotSelectedPart ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2022-11-07 09:41:43 +00:00
if ( ( Document : : EditMode : : Select = = m_document - > editMode ) & & ! m_lastCheckedPart . isNull ( ) ) {
const Document : : Part * part = m_document - > findPart ( m_lastCheckedPart ) ;
2018-10-24 13:44:21 +00:00
bool partRounded = part & & part - > rounded ;
emit setPartRoundState ( m_lastCheckedPart , ! partRounded ) ;
emit groupOperationAdded ( ) ;
}
}
2022-10-18 09:35:04 +00:00
bool SkeletonGraphicsWidget : : keyPress ( QKeyEvent * event )
2018-10-24 13:44:21 +00:00
{
if ( event - > key ( ) = = Qt : : Key_Space ) {
2022-11-07 09:41:43 +00:00
if ( Document : : EditMode : : ZoomIn = = m_document - > editMode | | Document : : EditMode : : ZoomOut = = m_document - > editMode | | Document : : EditMode : : Select = = m_document - > editMode | | Document : : EditMode : : Add = = m_document - > editMode ) {
2018-10-24 13:44:21 +00:00
m_inTempDragMode = true ;
m_modeBeforeEnterTempDragMode = m_document - > editMode ;
2022-11-07 09:41:43 +00:00
emit setEditMode ( Document : : EditMode : : Drag ) ;
2018-08-29 15:42:04 +00:00
return true ;
2018-04-26 02:23:22 +00:00
}
2018-10-24 13:44:21 +00:00
}
2022-10-18 09:35:04 +00:00
2018-10-24 13:44:21 +00:00
return false ;
}
2022-10-18 09:35:04 +00:00
bool SkeletonGraphicsWidget : : keyRelease ( QKeyEvent * event )
2018-10-24 13:44:21 +00:00
{
if ( event - > key ( ) = = Qt : : Key_Space ) {
if ( m_inTempDragMode ) {
m_inTempDragMode = false ;
emit setEditMode ( m_modeBeforeEnterTempDragMode ) ;
2018-08-31 04:54:32 +00:00
return true ;
}
2018-04-07 08:44:39 +00:00
}
2022-10-18 09:35:04 +00:00
2018-04-07 08:44:39 +00:00
return false ;
}
2018-04-15 12:11:51 +00:00
void SkeletonGraphicsWidget : : originChanged ( )
{
if ( ! m_document - > originSettled ( ) ) {
m_mainOriginItem - > hide ( ) ;
m_sideOriginItem - > hide ( ) ;
return ;
}
2019-10-19 13:14:36 +00:00
m_mainOriginItem - > setOrigin ( scenePosFromUnified ( QPointF ( m_document - > getOriginX ( m_rotated ) , m_document - > getOriginY ( m_rotated ) ) ) ) ;
m_sideOriginItem - > setOrigin ( scenePosFromUnified ( QPointF ( m_document - > getOriginZ ( m_rotated ) , m_document - > getOriginY ( m_rotated ) ) ) ) ;
2018-04-15 12:11:51 +00:00
m_mainOriginItem - > show ( ) ;
m_sideOriginItem - > show ( ) ;
}
2021-11-18 14:58:01 +00:00
void SkeletonGraphicsWidget : : nodeAdded ( dust3d : : Uuid nodeId )
2018-04-07 08:44:39 +00:00
{
2022-11-07 09:41:43 +00:00
const Document : : Node * node = m_document - > findNode ( nodeId ) ;
2018-04-07 08:44:39 +00:00
if ( nullptr = = node ) {
qDebug ( ) < < " New node added but node id not exist: " < < nodeId ;
return ;
}
2018-04-09 08:46:06 +00:00
if ( nodeItemMap . find ( nodeId ) ! = nodeItemMap . end ( ) ) {
qDebug ( ) < < " New node added but node item already exist: " < < nodeId ;
return ;
}
2022-11-07 09:41:43 +00:00
SkeletonGraphicsNodeItem * mainProfileItem = new SkeletonGraphicsNodeItem ( Document : : Profile : : Main ) ;
2019-10-19 13:14:36 +00:00
mainProfileItem - > setRotated ( m_rotated ) ;
2022-11-07 09:41:43 +00:00
SkeletonGraphicsNodeItem * sideProfileItem = new SkeletonGraphicsNodeItem ( Document : : Profile : : Side ) ;
2019-10-19 13:14:36 +00:00
sideProfileItem - > setRotated ( m_rotated ) ;
mainProfileItem - > setOrigin ( scenePosFromUnified ( QPointF ( node - > getX ( m_rotated ) , node - > getY ( m_rotated ) ) ) ) ;
sideProfileItem - > setOrigin ( scenePosFromUnified ( QPointF ( node - > getZ ( m_rotated ) , node - > getY ( m_rotated ) ) ) ) ;
2018-04-07 08:44:39 +00:00
mainProfileItem - > setRadius ( sceneRadiusFromUnified ( node - > radius ) ) ;
sideProfileItem - > setRadius ( sceneRadiusFromUnified ( node - > radius ) ) ;
mainProfileItem - > setId ( nodeId ) ;
sideProfileItem - > setId ( nodeId ) ;
scene ( ) - > addItem ( mainProfileItem ) ;
scene ( ) - > addItem ( sideProfileItem ) ;
nodeItemMap [ nodeId ] = std : : make_pair ( mainProfileItem , sideProfileItem ) ;
2022-10-18 09:35:04 +00:00
2018-04-08 15:08:23 +00:00
if ( nullptr = = m_addFromNodeItem ) {
m_addFromNodeItem = mainProfileItem ;
2018-04-07 08:44:39 +00:00
} else {
2022-11-07 09:41:43 +00:00
if ( Document : : Profile : : Main = = m_addFromNodeItem - > profile ( ) ) {
2018-04-08 15:08:23 +00:00
m_addFromNodeItem = mainProfileItem ;
2018-04-07 08:44:39 +00:00
} else {
2018-04-08 15:08:23 +00:00
m_addFromNodeItem = sideProfileItem ;
2018-04-07 08:44:39 +00:00
}
2018-04-08 15:08:23 +00:00
m_cursorEdgeItem - > setEndpoints ( m_addFromNodeItem , m_cursorNodeItem ) ;
2018-04-07 08:44:39 +00:00
}
}
2021-11-18 14:58:01 +00:00
void SkeletonGraphicsWidget : : edgeReversed ( dust3d : : Uuid edgeId )
2020-04-07 23:15:20 +00:00
{
2022-11-07 09:41:43 +00:00
const Document : : Edge * edge = m_document - > findEdge ( edgeId ) ;
2020-04-07 23:15:20 +00:00
if ( nullptr = = edge ) {
qDebug ( ) < < " Edge changed but edge id not exist: " < < edgeId ;
return ;
}
auto edgeItemIt = edgeItemMap . find ( edgeId ) ;
if ( edgeItemIt = = edgeItemMap . end ( ) ) {
qDebug ( ) < < " Edge removed but edge id not exist: " < < edgeId ;
return ;
}
edgeItemIt - > second . first - > reverse ( ) ;
edgeItemIt - > second . second - > reverse ( ) ;
}
2021-11-18 14:58:01 +00:00
void SkeletonGraphicsWidget : : edgeAdded ( dust3d : : Uuid edgeId )
2018-04-07 08:44:39 +00:00
{
2022-11-07 09:41:43 +00:00
const Document : : Edge * edge = m_document - > findEdge ( edgeId ) ;
2018-04-07 08:44:39 +00:00
if ( nullptr = = edge ) {
qDebug ( ) < < " New edge added but edge id not exist: " < < edgeId ;
return ;
}
if ( edge - > nodeIds . size ( ) ! = 2 ) {
qDebug ( ) < < " Invalid node count of edge: " < < edgeId ;
return ;
}
2021-11-18 14:58:01 +00:00
dust3d : : Uuid fromNodeId = edge - > nodeIds [ 0 ] ;
dust3d : : Uuid toNodeId = edge - > nodeIds [ 1 ] ;
2018-04-07 08:44:39 +00:00
auto fromIt = nodeItemMap . find ( fromNodeId ) ;
if ( fromIt = = nodeItemMap . end ( ) ) {
qDebug ( ) < < " Node not found: " < < fromNodeId ;
return ;
}
auto toIt = nodeItemMap . find ( toNodeId ) ;
if ( toIt = = nodeItemMap . end ( ) ) {
qDebug ( ) < < " Node not found: " < < toNodeId ;
return ;
}
2018-04-09 08:46:06 +00:00
if ( edgeItemMap . find ( edgeId ) ! = edgeItemMap . end ( ) ) {
qDebug ( ) < < " New edge added but edge item already exist: " < < edgeId ;
return ;
}
2022-10-18 09:35:04 +00:00
SkeletonGraphicsEdgeItem * mainProfileEdgeItem = new SkeletonGraphicsEdgeItem ( ) ;
2019-10-19 13:14:36 +00:00
mainProfileEdgeItem - > setRotated ( m_rotated ) ;
2022-10-18 09:35:04 +00:00
SkeletonGraphicsEdgeItem * sideProfileEdgeItem = new SkeletonGraphicsEdgeItem ( ) ;
2019-10-19 13:14:36 +00:00
sideProfileEdgeItem - > setRotated ( m_rotated ) ;
2018-04-07 08:44:39 +00:00
mainProfileEdgeItem - > setId ( edgeId ) ;
sideProfileEdgeItem - > setId ( edgeId ) ;
mainProfileEdgeItem - > setEndpoints ( fromIt - > second . first , toIt - > second . first ) ;
sideProfileEdgeItem - > setEndpoints ( fromIt - > second . second , toIt - > second . second ) ;
scene ( ) - > addItem ( mainProfileEdgeItem ) ;
scene ( ) - > addItem ( sideProfileEdgeItem ) ;
edgeItemMap [ edgeId ] = std : : make_pair ( mainProfileEdgeItem , sideProfileEdgeItem ) ;
}
2022-10-18 09:35:04 +00:00
void SkeletonGraphicsWidget : : removeItem ( QGraphicsItem * item )
2018-04-08 15:08:23 +00:00
{
if ( m_hoveredNodeItem = = item )
m_hoveredNodeItem = nullptr ;
if ( m_addFromNodeItem = = item )
m_addFromNodeItem = nullptr ;
if ( m_hoveredEdgeItem = = item )
m_hoveredEdgeItem = nullptr ;
m_rangeSelectionSet . erase ( item ) ;
}
2021-11-18 14:58:01 +00:00
void SkeletonGraphicsWidget : : nodeRemoved ( dust3d : : Uuid nodeId )
2018-04-07 08:44:39 +00:00
{
m_lastAddedX = 0 ;
m_lastAddedY = 0 ;
m_lastAddedZ = 0 ;
auto nodeItemIt = nodeItemMap . find ( nodeId ) ;
if ( nodeItemIt = = nodeItemMap . end ( ) ) {
qDebug ( ) < < " Node removed but node id not exist: " < < nodeId ;
return ;
}
2018-04-08 15:08:23 +00:00
removeItem ( nodeItemIt - > second . first ) ;
removeItem ( nodeItemIt - > second . second ) ;
2018-04-07 08:44:39 +00:00
delete nodeItemIt - > second . first ;
delete nodeItemIt - > second . second ;
nodeItemMap . erase ( nodeItemIt ) ;
}
2021-11-18 14:58:01 +00:00
void SkeletonGraphicsWidget : : edgeRemoved ( dust3d : : Uuid edgeId )
2018-04-07 08:44:39 +00:00
{
auto edgeItemIt = edgeItemMap . find ( edgeId ) ;
if ( edgeItemIt = = edgeItemMap . end ( ) ) {
qDebug ( ) < < " Edge removed but edge id not exist: " < < edgeId ;
return ;
}
2018-04-08 15:08:23 +00:00
removeItem ( edgeItemIt - > second . first ) ;
removeItem ( edgeItemIt - > second . second ) ;
2018-04-07 08:44:39 +00:00
delete edgeItemIt - > second . first ;
delete edgeItemIt - > second . second ;
edgeItemMap . erase ( edgeItemIt ) ;
}
2021-11-18 14:58:01 +00:00
void SkeletonGraphicsWidget : : nodeRadiusChanged ( dust3d : : Uuid nodeId )
2018-04-07 08:44:39 +00:00
{
2022-11-07 09:41:43 +00:00
const Document : : Node * node = m_document - > findNode ( nodeId ) ;
2018-04-07 08:44:39 +00:00
if ( nullptr = = node ) {
qDebug ( ) < < " Node changed but node id not exist: " < < nodeId ;
return ;
}
auto it = nodeItemMap . find ( nodeId ) ;
if ( it = = nodeItemMap . end ( ) ) {
qDebug ( ) < < " Node not found: " < < nodeId ;
return ;
}
float sceneRadius = sceneRadiusFromUnified ( node - > radius ) ;
it - > second . first - > setRadius ( sceneRadius ) ;
it - > second . second - > setRadius ( sceneRadius ) ;
}
2021-11-18 14:58:01 +00:00
void SkeletonGraphicsWidget : : nodeOriginChanged ( dust3d : : Uuid nodeId )
2018-04-07 08:44:39 +00:00
{
2022-11-07 09:41:43 +00:00
const Document : : Node * node = m_document - > findNode ( nodeId ) ;
2018-04-07 08:44:39 +00:00
if ( nullptr = = node ) {
qDebug ( ) < < " Node changed but node id not exist: " < < nodeId ;
return ;
}
auto it = nodeItemMap . find ( nodeId ) ;
if ( it = = nodeItemMap . end ( ) ) {
qDebug ( ) < < " Node not found: " < < nodeId ;
return ;
}
2019-10-19 13:14:36 +00:00
QPointF mainPos = scenePosFromUnified ( QPointF ( node - > getX ( m_rotated ) , node - > getY ( m_rotated ) ) ) ;
QPointF sidePos = scenePosFromUnified ( QPointF ( node - > getZ ( m_rotated ) , node - > getY ( m_rotated ) ) ) ;
2018-04-07 08:44:39 +00:00
it - > second . first - > setOrigin ( mainPos ) ;
2019-10-19 13:14:36 +00:00
it - > second . first - > setRotated ( m_rotated ) ;
it - > second . first - > updateAppearance ( ) ;
2018-04-07 08:44:39 +00:00
it - > second . second - > setOrigin ( sidePos ) ;
2019-10-19 13:14:36 +00:00
it - > second . second - > setRotated ( m_rotated ) ;
it - > second . second - > updateAppearance ( ) ;
2018-04-07 08:44:39 +00:00
for ( auto edgeIt = node - > edgeIds . begin ( ) ; edgeIt ! = node - > edgeIds . end ( ) ; edgeIt + + ) {
auto edgeItemIt = edgeItemMap . find ( * edgeIt ) ;
if ( edgeItemIt = = edgeItemMap . end ( ) ) {
qDebug ( ) < < " Edge item not found: " < < * edgeIt ;
continue ;
}
2019-10-19 13:14:36 +00:00
edgeItemIt - > second . first - > setRotated ( m_rotated ) ;
2018-04-07 08:44:39 +00:00
edgeItemIt - > second . first - > updateAppearance ( ) ;
2019-10-19 13:14:36 +00:00
edgeItemIt - > second . second - > setRotated ( m_rotated ) ;
2018-04-07 08:44:39 +00:00
edgeItemIt - > second . second - > updateAppearance ( ) ;
}
}
2021-11-18 14:58:01 +00:00
void SkeletonGraphicsWidget : : partVisibleStateChanged ( dust3d : : Uuid partId )
2018-04-08 01:30:55 +00:00
{
2022-11-07 09:41:43 +00:00
const Document : : Part * part = m_document - > findPart ( partId ) ;
2022-10-18 09:35:04 +00:00
for ( const auto & nodeId : part - > nodeIds ) {
2022-11-07 09:41:43 +00:00
const Document : : Node * node = m_document - > findNode ( nodeId ) ;
2018-04-08 01:30:55 +00:00
for ( auto edgeIt = node - > edgeIds . begin ( ) ; edgeIt ! = node - > edgeIds . end ( ) ; edgeIt + + ) {
auto edgeItemIt = edgeItemMap . find ( * edgeIt ) ;
if ( edgeItemIt = = edgeItemMap . end ( ) ) {
qDebug ( ) < < " Edge item not found: " < < * edgeIt ;
continue ;
}
2018-04-16 12:06:48 +00:00
edgeItemIt - > second . first - > setVisible ( part - > isEditVisible ( ) ) ;
edgeItemIt - > second . second - > setVisible ( part - > isEditVisible ( ) ) ;
2018-04-08 01:30:55 +00:00
}
auto nodeItemIt = nodeItemMap . find ( nodeId ) ;
if ( nodeItemIt = = nodeItemMap . end ( ) ) {
qDebug ( ) < < " Node item not found: " < < nodeId ;
continue ;
}
2018-04-16 12:06:48 +00:00
nodeItemIt - > second . first - > setVisible ( part - > isEditVisible ( ) ) ;
nodeItemIt - > second . second - > setVisible ( part - > isEditVisible ( ) ) ;
2018-04-08 01:30:55 +00:00
}
}
2022-10-18 09:35:04 +00:00
bool SkeletonGraphicsWidget : : checkSkeletonItem ( QGraphicsItem * item , bool checked )
2018-04-08 15:08:23 +00:00
{
2018-04-10 08:44:02 +00:00
if ( checked ) {
if ( ! item - > isVisible ( ) )
return false ;
}
2018-04-08 15:08:23 +00:00
if ( item - > data ( 0 ) = = " node " ) {
2022-10-18 09:35:04 +00:00
SkeletonGraphicsNodeItem * nodeItem = ( SkeletonGraphicsNodeItem * ) item ;
2018-04-13 00:19:31 +00:00
if ( checked ) {
if ( ! m_document - > isNodeEditable ( nodeItem - > id ( ) ) ) {
return false ;
}
}
2018-04-08 15:08:23 +00:00
if ( checked ! = nodeItem - > checked ( ) )
nodeItem - > setChecked ( checked ) ;
return true ;
} else if ( item - > data ( 0 ) = = " edge " ) {
2022-10-18 09:35:04 +00:00
SkeletonGraphicsEdgeItem * edgeItem = ( SkeletonGraphicsEdgeItem * ) item ;
2018-04-13 00:19:31 +00:00
if ( checked ) {
if ( ! m_document - > isEdgeEditable ( edgeItem - > id ( ) ) ) {
return false ;
}
}
2018-04-08 15:08:23 +00:00
if ( checked ! = edgeItem - > checked ( ) )
edgeItem - > setChecked ( checked ) ;
return true ;
}
return false ;
}
2022-10-18 09:35:04 +00:00
dust3d : : Uuid SkeletonGraphicsWidget : : querySkeletonItemPartId ( QGraphicsItem * item )
2018-04-18 01:49:23 +00:00
{
if ( item - > data ( 0 ) = = " node " ) {
2022-10-18 09:35:04 +00:00
SkeletonGraphicsNodeItem * nodeItem = ( SkeletonGraphicsNodeItem * ) item ;
2022-11-07 09:41:43 +00:00
const Document : : Node * node = m_document - > findNode ( nodeItem - > id ( ) ) ;
2018-04-18 01:49:23 +00:00
if ( ! node ) {
qDebug ( ) < < " Find node id failed: " < < nodeItem - > id ( ) ;
2021-11-18 14:58:01 +00:00
return dust3d : : Uuid ( ) ;
2018-04-18 01:49:23 +00:00
}
return node - > partId ;
} else if ( item - > data ( 0 ) = = " edge " ) {
2022-10-18 09:35:04 +00:00
SkeletonGraphicsEdgeItem * edgeItem = ( SkeletonGraphicsEdgeItem * ) item ;
2022-11-07 09:41:43 +00:00
const Document : : Edge * edge = m_document - > findEdge ( edgeItem - > id ( ) ) ;
2018-04-18 01:49:23 +00:00
if ( ! edge ) {
qDebug ( ) < < " Find edge id failed: " < < edgeItem - > id ( ) ;
2021-11-18 14:58:01 +00:00
return dust3d : : Uuid ( ) ;
2018-04-18 01:49:23 +00:00
}
return edge - > partId ;
}
2021-11-18 14:58:01 +00:00
return dust3d : : Uuid ( ) ;
2018-04-18 01:49:23 +00:00
}
2022-11-07 09:41:43 +00:00
Document : : Profile SkeletonGraphicsWidget : : readSkeletonItemProfile ( QGraphicsItem * item )
2018-04-08 15:08:23 +00:00
{
if ( item - > data ( 0 ) = = " node " ) {
2022-10-18 09:35:04 +00:00
SkeletonGraphicsNodeItem * nodeItem = ( SkeletonGraphicsNodeItem * ) item ;
2018-04-08 15:08:23 +00:00
return nodeItem - > profile ( ) ;
} else if ( item - > data ( 0 ) = = " edge " ) {
2022-10-18 09:35:04 +00:00
SkeletonGraphicsEdgeItem * edgeItem = ( SkeletonGraphicsEdgeItem * ) item ;
2018-04-08 15:08:23 +00:00
return edgeItem - > profile ( ) ;
}
2022-11-07 09:41:43 +00:00
return Document : : Profile : : Unknown ;
2018-04-08 15:08:23 +00:00
}
void SkeletonGraphicsWidget : : checkRangeSelection ( )
{
2022-10-18 09:35:04 +00:00
std : : set < QGraphicsItem * > newSet ;
std : : set < QGraphicsItem * > deleteSet ;
std : : set < QGraphicsItem * > forceDeleteSet ;
2022-11-07 09:41:43 +00:00
Document : : Profile choosenProfile = Document : : Profile : : Unknown ;
2018-04-08 15:08:23 +00:00
if ( ! m_rangeSelectionSet . empty ( ) ) {
auto it = m_rangeSelectionSet . begin ( ) ;
choosenProfile = readSkeletonItemProfile ( * it ) ;
}
if ( m_selectionItem - > isVisible ( ) ) {
2022-10-18 09:35:04 +00:00
QList < QGraphicsItem * > items = scene ( ) - > items ( m_selectionItem - > sceneBoundingRect ( ) ) ;
2018-04-08 15:08:23 +00:00
for ( auto it = items . begin ( ) ; it ! = items . end ( ) ; it + + ) {
2022-10-18 09:35:04 +00:00
QGraphicsItem * item = * it ;
2018-04-12 13:24:51 +00:00
if ( QGuiApplication : : queryKeyboardModifiers ( ) . testFlag ( Qt : : AltModifier ) ) {
checkSkeletonItem ( item , false ) ;
forceDeleteSet . insert ( item ) ;
} else {
2022-11-07 09:41:43 +00:00
if ( Document : : Profile : : Unknown = = choosenProfile ) {
2018-04-12 13:24:51 +00:00
if ( checkSkeletonItem ( item , true ) ) {
choosenProfile = readSkeletonItemProfile ( item ) ;
newSet . insert ( item ) ;
}
} else if ( choosenProfile = = readSkeletonItemProfile ( item ) ) {
if ( checkSkeletonItem ( item , true ) )
newSet . insert ( item ) ;
2018-04-08 15:08:23 +00:00
}
}
}
}
if ( ! QGuiApplication : : queryKeyboardModifiers ( ) . testFlag ( Qt : : ControlModifier ) ) {
2022-10-18 09:35:04 +00:00
for ( const auto & item : m_rangeSelectionSet ) {
2018-04-08 15:08:23 +00:00
if ( newSet . find ( item ) = = newSet . end ( ) ) {
checkSkeletonItem ( item , false ) ;
deleteSet . insert ( item ) ;
}
}
}
2022-10-18 09:35:04 +00:00
for ( const auto & item : newSet ) {
2018-04-08 15:08:23 +00:00
m_rangeSelectionSet . insert ( item ) ;
}
2022-10-18 09:35:04 +00:00
for ( const auto & item : deleteSet ) {
2018-04-08 15:08:23 +00:00
m_rangeSelectionSet . erase ( item ) ;
}
2022-10-18 09:35:04 +00:00
for ( const auto & item : forceDeleteSet ) {
2018-04-12 13:24:51 +00:00
m_rangeSelectionSet . erase ( item ) ;
}
2018-04-08 15:08:23 +00:00
}
void SkeletonGraphicsWidget : : clearRangeSelection ( )
{
2022-10-18 09:35:04 +00:00
for ( const auto & item : m_rangeSelectionSet ) {
2018-04-08 15:08:23 +00:00
checkSkeletonItem ( item , false ) ;
}
m_rangeSelectionSet . clear ( ) ;
}
2022-10-18 09:35:04 +00:00
void SkeletonGraphicsWidget : : readMergedSkeletonNodeSetFromRangeSelection ( std : : set < SkeletonGraphicsNodeItem * > * nodeItemSet )
2018-04-08 15:08:23 +00:00
{
2022-10-18 09:35:04 +00:00
for ( const auto & it : m_rangeSelectionSet ) {
QGraphicsItem * item = it ;
2018-04-08 15:08:23 +00:00
if ( item - > data ( 0 ) = = " node " ) {
2022-10-18 09:35:04 +00:00
nodeItemSet - > insert ( ( SkeletonGraphicsNodeItem * ) item ) ;
2018-04-08 15:08:23 +00:00
} else if ( item - > data ( 0 ) = = " edge " ) {
2022-10-18 09:35:04 +00:00
SkeletonGraphicsEdgeItem * edgeItem = ( SkeletonGraphicsEdgeItem * ) item ;
2018-04-08 15:08:23 +00:00
if ( edgeItem - > firstItem ( ) & & edgeItem - > secondItem ( ) ) {
nodeItemSet - > insert ( edgeItem - > firstItem ( ) ) ;
nodeItemSet - > insert ( edgeItem - > secondItem ( ) ) ;
}
}
}
}
2022-10-18 09:35:04 +00:00
void SkeletonGraphicsWidget : : readSkeletonNodeAndEdgeIdSetFromRangeSelection ( std : : set < dust3d : : Uuid > * nodeIdSet , std : : set < dust3d : : Uuid > * edgeIdSet )
2018-04-08 15:08:23 +00:00
{
2022-10-18 09:35:04 +00:00
for ( const auto & it : m_rangeSelectionSet ) {
QGraphicsItem * item = it ;
2018-04-08 15:08:23 +00:00
if ( item - > data ( 0 ) = = " node " ) {
2022-10-18 09:35:04 +00:00
nodeIdSet - > insert ( ( ( SkeletonGraphicsNodeItem * ) item ) - > id ( ) ) ;
2018-04-08 15:08:23 +00:00
} else if ( item - > data ( 0 ) = = " edge " ) {
2018-06-21 08:24:18 +00:00
if ( nullptr ! = edgeIdSet )
2022-10-18 09:35:04 +00:00
edgeIdSet - > insert ( ( ( SkeletonGraphicsEdgeItem * ) item ) - > id ( ) ) ;
2018-04-08 15:08:23 +00:00
}
}
}
2022-10-18 09:35:04 +00:00
bool SkeletonGraphicsWidget : : readSkeletonNodeAndAnyEdgeOfNodeFromRangeSelection ( SkeletonGraphicsNodeItem * * nodeItem , SkeletonGraphicsEdgeItem * * edgeItem )
2018-04-09 11:13:34 +00:00
{
2022-10-18 09:35:04 +00:00
SkeletonGraphicsNodeItem * choosenNodeItem = nullptr ;
SkeletonGraphicsEdgeItem * choosenEdgeItem = nullptr ;
for ( const auto & it : m_rangeSelectionSet ) {
QGraphicsItem * item = it ;
2018-04-09 11:13:34 +00:00
if ( item - > data ( 0 ) = = " node " ) {
2022-10-18 09:35:04 +00:00
choosenNodeItem = ( SkeletonGraphicsNodeItem * ) item ;
2018-04-09 11:13:34 +00:00
} else if ( item - > data ( 0 ) = = " edge " ) {
2022-10-18 09:35:04 +00:00
choosenEdgeItem = ( SkeletonGraphicsEdgeItem * ) item ;
2018-04-09 11:13:34 +00:00
}
if ( choosenNodeItem & & choosenEdgeItem )
break ;
}
if ( ! choosenNodeItem | | ! choosenEdgeItem )
return false ;
if ( choosenNodeItem - > profile ( ) ! = choosenEdgeItem - > profile ( ) )
return false ;
if ( choosenNodeItem ! = choosenEdgeItem - > firstItem ( ) & & choosenNodeItem ! = choosenEdgeItem - > secondItem ( ) )
return false ;
if ( nodeItem )
* nodeItem = choosenNodeItem ;
if ( edgeItem )
* edgeItem = choosenEdgeItem ;
if ( m_rangeSelectionSet . size ( ) ! = 2 )
return false ;
return true ;
}
2021-11-18 14:58:01 +00:00
void SkeletonGraphicsWidget : : selectPartAllById ( dust3d : : Uuid partId )
2018-04-18 01:49:23 +00:00
{
unselectAll ( ) ;
2022-10-18 09:35:04 +00:00
for ( const auto & it : nodeItemMap ) {
SkeletonGraphicsNodeItem * item = it . second . first ;
2022-11-07 09:41:43 +00:00
const Document : : Node * node = m_document - > findNode ( item - > id ( ) ) ;
2018-04-18 01:49:23 +00:00
if ( ! node )
continue ;
if ( node - > partId ! = partId )
continue ;
addItemToRangeSelection ( item ) ;
}
2022-10-18 09:35:04 +00:00
for ( const auto & it : edgeItemMap ) {
SkeletonGraphicsEdgeItem * item = it . second . first ;
2022-11-07 09:41:43 +00:00
const Document : : Edge * edge = m_document - > findEdge ( item - > id ( ) ) ;
2018-04-18 01:49:23 +00:00
if ( ! edge )
continue ;
if ( edge - > partId ! = partId )
continue ;
addItemToRangeSelection ( item ) ;
}
2021-11-18 14:58:01 +00:00
hoverPart ( dust3d : : Uuid ( ) ) ;
2018-04-18 01:49:23 +00:00
}
2021-11-18 14:58:01 +00:00
void SkeletonGraphicsWidget : : addSelectNode ( dust3d : : Uuid nodeId )
2018-05-12 10:07:46 +00:00
{
2022-10-18 09:35:04 +00:00
const auto & findResult = nodeItemMap . find ( nodeId ) ;
2018-05-12 10:07:46 +00:00
if ( findResult = = nodeItemMap . end ( ) ) {
qDebug ( ) < < " addSelectNode failed because of node id not exists:<< " < < nodeId ;
return ;
}
addItemToRangeSelection ( findResult - > second . first ) ;
2021-11-18 14:58:01 +00:00
hoverPart ( dust3d : : Uuid ( ) ) ;
2018-05-12 10:07:46 +00:00
}
2021-11-18 14:58:01 +00:00
void SkeletonGraphicsWidget : : addSelectEdge ( dust3d : : Uuid edgeId )
2018-05-12 10:07:46 +00:00
{
2022-10-18 09:35:04 +00:00
const auto & findResult = edgeItemMap . find ( edgeId ) ;
2018-05-12 10:07:46 +00:00
if ( findResult = = edgeItemMap . end ( ) ) {
qDebug ( ) < < " addSelectEdge failed because of edge id not exists:<< " < < edgeId ;
return ;
}
addItemToRangeSelection ( findResult - > second . first ) ;
2021-11-18 14:58:01 +00:00
hoverPart ( dust3d : : Uuid ( ) ) ;
2018-05-12 10:07:46 +00:00
}
2021-11-18 14:58:01 +00:00
void SkeletonGraphicsWidget : : addPartToSelection ( dust3d : : Uuid partId )
2018-09-01 02:17:26 +00:00
{
2022-11-07 09:41:43 +00:00
Document : : Profile choosenProfile = Document : : Profile : : Main ;
2018-09-01 02:17:26 +00:00
if ( m_hoveredNodeItem ) {
choosenProfile = m_hoveredNodeItem - > profile ( ) ;
} else if ( m_hoveredEdgeItem ) {
choosenProfile = m_hoveredEdgeItem - > profile ( ) ;
}
2021-11-18 14:58:01 +00:00
dust3d : : Uuid choosenPartId = partId ;
2022-10-18 09:35:04 +00:00
for ( const auto & it : nodeItemMap ) {
2022-11-07 09:41:43 +00:00
SkeletonGraphicsNodeItem * item = Document : : Profile : : Main = = choosenProfile ? it . second . first : it . second . second ;
const Document : : Node * node = m_document - > findNode ( item - > id ( ) ) ;
2018-09-01 02:17:26 +00:00
if ( ! node )
continue ;
if ( choosenPartId . isNull ( ) ) {
choosenPartId = node - > partId ;
}
if ( node - > partId ! = choosenPartId )
continue ;
addItemToRangeSelection ( item ) ;
}
2022-10-18 09:35:04 +00:00
for ( const auto & it : edgeItemMap ) {
2022-11-07 09:41:43 +00:00
SkeletonGraphicsEdgeItem * item = Document : : Profile : : Main = = choosenProfile ? it . second . first : it . second . second ;
const Document : : Edge * edge = m_document - > findEdge ( item - > id ( ) ) ;
2018-09-01 02:17:26 +00:00
if ( ! edge )
continue ;
if ( choosenPartId . isNull ( ) ) {
choosenPartId = edge - > partId ;
}
if ( edge - > partId ! = choosenPartId )
continue ;
addItemToRangeSelection ( item ) ;
}
}
2018-12-11 11:55:55 +00:00
void SkeletonGraphicsWidget : : selectConnectedAll ( )
{
unselectAll ( ) ;
2022-11-07 09:41:43 +00:00
Document : : Profile choosenProfile = Document : : Profile : : Main ;
2021-11-18 14:58:01 +00:00
dust3d : : Uuid startNodeId ;
2018-12-11 11:55:55 +00:00
if ( m_hoveredNodeItem ) {
choosenProfile = m_hoveredNodeItem - > profile ( ) ;
2022-11-07 09:41:43 +00:00
const Document : : Node * node = m_document - > findNode ( m_hoveredNodeItem - > id ( ) ) ;
2018-12-11 11:55:55 +00:00
if ( node )
startNodeId = node - > id ;
} else if ( m_hoveredEdgeItem ) {
choosenProfile = m_hoveredEdgeItem - > profile ( ) ;
2022-11-07 09:41:43 +00:00
const Document : : Edge * edge = m_document - > findEdge ( m_hoveredEdgeItem - > id ( ) ) ;
2018-12-11 11:55:55 +00:00
if ( edge & & ! edge - > nodeIds . empty ( ) )
startNodeId = * edge - > nodeIds . begin ( ) ;
}
if ( startNodeId . isNull ( ) )
return ;
2021-11-18 14:58:01 +00:00
std : : set < dust3d : : Uuid > visitedNodes ;
std : : set < dust3d : : Uuid > visitedEdges ;
std : : queue < dust3d : : Uuid > nodeIds ;
2018-12-11 11:55:55 +00:00
nodeIds . push ( startNodeId ) ;
while ( ! nodeIds . empty ( ) ) {
2021-11-18 14:58:01 +00:00
dust3d : : Uuid nodeId = nodeIds . front ( ) ;
2018-12-11 11:55:55 +00:00
nodeIds . pop ( ) ;
if ( visitedNodes . find ( nodeId ) ! = visitedNodes . end ( ) )
continue ;
2022-11-07 09:41:43 +00:00
const Document : : Node * node = m_document - > findNode ( nodeId ) ;
2018-12-11 11:55:55 +00:00
if ( nullptr = = node )
continue ;
visitedNodes . insert ( nodeId ) ;
2022-10-18 09:35:04 +00:00
for ( const auto & edgeId : node - > edgeIds ) {
2022-11-07 09:41:43 +00:00
const Document : : Edge * edge = m_document - > findEdge ( edgeId ) ;
2018-12-11 11:55:55 +00:00
if ( nullptr = = edge )
continue ;
visitedEdges . insert ( edgeId ) ;
2022-10-18 09:35:04 +00:00
for ( const auto & nodeIdOfEdge : edge - > nodeIds ) {
2018-12-11 11:55:55 +00:00
if ( visitedNodes . find ( nodeIdOfEdge ) ! = visitedNodes . end ( ) )
continue ;
nodeIds . push ( nodeIdOfEdge ) ;
}
}
}
2022-10-18 09:35:04 +00:00
for ( const auto & it : nodeItemMap ) {
2022-11-07 09:41:43 +00:00
SkeletonGraphicsNodeItem * item = Document : : Profile : : Main = = choosenProfile ? it . second . first : it . second . second ;
2018-12-11 11:55:55 +00:00
if ( visitedNodes . find ( item - > id ( ) ) = = visitedNodes . end ( ) )
continue ;
addItemToRangeSelection ( item ) ;
}
2022-10-18 09:35:04 +00:00
for ( const auto & it : edgeItemMap ) {
2022-11-07 09:41:43 +00:00
SkeletonGraphicsEdgeItem * item = Document : : Profile : : Main = = choosenProfile ? it . second . first : it . second . second ;
2018-12-11 11:55:55 +00:00
if ( visitedEdges . find ( item - > id ( ) ) = = visitedEdges . end ( ) )
continue ;
addItemToRangeSelection ( item ) ;
}
}
2018-04-09 05:22:25 +00:00
void SkeletonGraphicsWidget : : selectPartAll ( )
{
unselectAll ( ) ;
2022-11-07 09:41:43 +00:00
Document : : Profile choosenProfile = Document : : Profile : : Main ;
2021-11-18 14:58:01 +00:00
dust3d : : Uuid choosenPartId ;
2018-04-09 05:22:25 +00:00
if ( m_hoveredNodeItem ) {
choosenProfile = m_hoveredNodeItem - > profile ( ) ;
2022-11-07 09:41:43 +00:00
const Document : : Node * node = m_document - > findNode ( m_hoveredNodeItem - > id ( ) ) ;
2018-04-09 05:22:25 +00:00
if ( node )
choosenPartId = node - > partId ;
} else if ( m_hoveredEdgeItem ) {
choosenProfile = m_hoveredEdgeItem - > profile ( ) ;
2022-11-07 09:41:43 +00:00
const Document : : Edge * edge = m_document - > findEdge ( m_hoveredEdgeItem - > id ( ) ) ;
2018-04-09 05:22:25 +00:00
if ( edge )
choosenPartId = edge - > partId ;
}
2022-10-18 09:35:04 +00:00
for ( const auto & it : nodeItemMap ) {
2022-11-07 09:41:43 +00:00
SkeletonGraphicsNodeItem * item = Document : : Profile : : Main = = choosenProfile ? it . second . first : it . second . second ;
const Document : : Node * node = m_document - > findNode ( item - > id ( ) ) ;
2018-04-09 05:22:25 +00:00
if ( ! node )
continue ;
if ( choosenPartId . isNull ( ) ) {
choosenPartId = node - > partId ;
}
if ( node - > partId ! = choosenPartId )
continue ;
2018-04-10 08:44:02 +00:00
addItemToRangeSelection ( item ) ;
2018-04-09 05:22:25 +00:00
}
2022-10-18 09:35:04 +00:00
for ( const auto & it : edgeItemMap ) {
2022-11-07 09:41:43 +00:00
SkeletonGraphicsEdgeItem * item = Document : : Profile : : Main = = choosenProfile ? it . second . first : it . second . second ;
const Document : : Edge * edge = m_document - > findEdge ( item - > id ( ) ) ;
2018-04-09 05:22:25 +00:00
if ( ! edge )
continue ;
if ( choosenPartId . isNull ( ) ) {
choosenPartId = edge - > partId ;
}
if ( edge - > partId ! = choosenPartId )
continue ;
2018-04-10 08:44:02 +00:00
addItemToRangeSelection ( item ) ;
2018-04-09 05:22:25 +00:00
}
2019-10-18 22:32:24 +00:00
if ( ! choosenPartId . isNull ( ) ) {
emit partComponentChecked ( choosenPartId ) ;
2019-10-18 22:51:23 +00:00
}
}
void SkeletonGraphicsWidget : : shortcutCheckPartComponent ( )
{
2020-12-19 08:12:50 +00:00
if ( ! isVisible ( ) )
return ;
2022-10-18 09:35:04 +00:00
2021-11-18 14:58:01 +00:00
dust3d : : Uuid choosenPartId ;
2019-10-18 22:51:23 +00:00
if ( m_hoveredNodeItem ) {
2022-11-07 09:41:43 +00:00
const Document : : Node * node = m_document - > findNode ( m_hoveredNodeItem - > id ( ) ) ;
2019-10-18 22:51:23 +00:00
if ( node )
choosenPartId = node - > partId ;
} else if ( m_hoveredEdgeItem ) {
2022-11-07 09:41:43 +00:00
const Document : : Edge * edge = m_document - > findEdge ( m_hoveredEdgeItem - > id ( ) ) ;
2019-10-18 22:51:23 +00:00
if ( edge )
choosenPartId = edge - > partId ;
}
if ( ! choosenPartId . isNull ( ) ) {
emit partComponentChecked ( choosenPartId ) ;
2019-10-18 22:32:24 +00:00
}
2018-04-09 05:22:25 +00:00
}
2018-04-09 03:39:04 +00:00
void SkeletonGraphicsWidget : : selectAll ( )
{
unselectAll ( ) ;
2022-11-07 09:41:43 +00:00
Document : : Profile choosenProfile = Document : : Profile : : Main ;
2018-04-09 03:39:04 +00:00
if ( m_hoveredNodeItem ) {
choosenProfile = m_hoveredNodeItem - > profile ( ) ;
} else if ( m_hoveredEdgeItem ) {
choosenProfile = m_hoveredEdgeItem - > profile ( ) ;
}
2022-10-18 09:35:04 +00:00
for ( const auto & it : nodeItemMap ) {
2022-11-07 09:41:43 +00:00
SkeletonGraphicsNodeItem * item = Document : : Profile : : Main = = choosenProfile ? it . second . first : it . second . second ;
2018-04-10 08:44:02 +00:00
addItemToRangeSelection ( item ) ;
2018-04-09 03:39:04 +00:00
}
2022-10-18 09:35:04 +00:00
for ( const auto & it : edgeItemMap ) {
2022-11-07 09:41:43 +00:00
SkeletonGraphicsEdgeItem * item = Document : : Profile : : Main = = choosenProfile ? it . second . first : it . second . second ;
2018-04-10 08:44:02 +00:00
addItemToRangeSelection ( item ) ;
2018-04-09 03:39:04 +00:00
}
}
2022-10-18 09:35:04 +00:00
void SkeletonGraphicsWidget : : addItemToRangeSelection ( QGraphicsItem * item )
2018-04-10 08:44:02 +00:00
{
if ( ! item - > isVisible ( ) )
return ;
2018-04-13 00:19:31 +00:00
if ( checkSkeletonItem ( item , true ) )
m_rangeSelectionSet . insert ( item ) ;
2018-04-10 08:44:02 +00:00
}
2022-10-18 09:35:04 +00:00
void SkeletonGraphicsWidget : : removeItemFromRangeSelection ( QGraphicsItem * item )
2018-04-10 08:44:02 +00:00
{
checkSkeletonItem ( item , false ) ;
m_rangeSelectionSet . erase ( item ) ;
}
2018-04-09 03:39:04 +00:00
void SkeletonGraphicsWidget : : unselectAll ( )
{
2022-10-18 09:35:04 +00:00
for ( const auto & item : m_rangeSelectionSet ) {
2018-04-09 03:39:04 +00:00
checkSkeletonItem ( item , false ) ;
}
m_rangeSelectionSet . clear ( ) ;
}
2018-04-09 08:46:06 +00:00
void SkeletonGraphicsWidget : : cut ( )
{
copy ( ) ;
deleteSelected ( ) ;
}
void SkeletonGraphicsWidget : : copy ( )
{
2021-11-18 14:58:01 +00:00
std : : set < dust3d : : Uuid > nodeIdSet ;
std : : set < dust3d : : Uuid > edgeIdSet ;
2018-04-09 08:46:06 +00:00
readSkeletonNodeAndEdgeIdSetFromRangeSelection ( & nodeIdSet , & edgeIdSet ) ;
if ( nodeIdSet . empty ( ) )
return ;
2018-11-03 08:09:42 +00:00
m_document - > copyNodes ( nodeIdSet ) ;
2018-04-09 08:46:06 +00:00
}
2018-04-09 14:24:30 +00:00
2018-04-10 07:59:20 +00:00
void SkeletonGraphicsWidget : : removeAllContent ( )
{
nodeItemMap . clear ( ) ;
edgeItemMap . clear ( ) ;
m_rangeSelectionSet . clear ( ) ;
m_hoveredEdgeItem = nullptr ;
m_hoveredNodeItem = nullptr ;
m_addFromNodeItem = nullptr ;
m_cursorEdgeItem - > hide ( ) ;
m_cursorNodeItem - > hide ( ) ;
2022-10-18 09:35:04 +00:00
std : : vector < QGraphicsItem * > contentItems ;
for ( const auto & it : items ( ) ) {
QGraphicsItem * item = it ;
2018-04-10 07:59:20 +00:00
if ( item - > data ( 0 ) = = " node " ) {
2018-08-27 08:50:40 +00:00
contentItems . push_back ( item ) ;
2018-04-10 07:59:20 +00:00
} else if ( item - > data ( 0 ) = = " edge " ) {
2018-08-27 08:50:40 +00:00
contentItems . push_back ( item ) ;
2018-04-10 07:59:20 +00:00
}
}
2018-08-27 08:50:40 +00:00
for ( size_t i = 0 ; i < contentItems . size ( ) ; i + + ) {
2022-10-18 09:35:04 +00:00
QGraphicsItem * item = contentItems [ i ] ;
2018-04-10 07:59:20 +00:00
Q_ASSERT ( item ! = m_cursorEdgeItem ) ;
Q_ASSERT ( item ! = m_cursorNodeItem ) ;
2018-08-27 08:50:40 +00:00
delete item ;
2018-04-10 07:59:20 +00:00
}
}
2018-04-09 14:37:20 +00:00
bool SkeletonGraphicsWidget : : isSingleNodeSelected ( )
{
if ( m_rangeSelectionSet . size ( ) ! = 1 )
return false ;
2022-10-18 09:35:04 +00:00
const auto & it = m_rangeSelectionSet . begin ( ) ;
QGraphicsItem * item = * it ;
2018-04-09 14:37:20 +00:00
return item - > data ( 0 ) = = " node " ;
}
2018-04-09 14:24:30 +00:00
2021-11-18 14:58:01 +00:00
void SkeletonGraphicsWidget : : hoverPart ( dust3d : : Uuid partId )
2018-04-18 01:49:23 +00:00
{
if ( partId . isNull ( ) ) {
if ( ! m_rangeSelectionSet . empty ( ) ) {
2022-10-18 09:35:04 +00:00
const auto & it = m_rangeSelectionSet . begin ( ) ;
2018-04-18 01:49:23 +00:00
partId = querySkeletonItemPartId ( * it ) ;
}
}
2022-10-18 09:35:04 +00:00
2018-04-18 01:49:23 +00:00
if ( m_lastCheckedPart = = partId )
return ;
2022-10-18 09:35:04 +00:00
2018-04-18 01:49:23 +00:00
if ( ! m_lastCheckedPart . isNull ( ) )
emit partUnchecked ( m_lastCheckedPart ) ;
m_lastCheckedPart = partId ;
if ( ! m_lastCheckedPart . isNull ( ) )
emit partChecked ( m_lastCheckedPart ) ;
}
2018-04-18 02:16:54 +00:00
void SkeletonGraphicsWidget : : switchProfileOnRangeSelection ( )
{
auto copiedSet = m_rangeSelectionSet ;
2022-10-18 09:35:04 +00:00
for ( const auto & item : copiedSet ) {
2018-04-18 02:16:54 +00:00
if ( item - > data ( 0 ) = = " node " ) {
2022-10-18 09:35:04 +00:00
SkeletonGraphicsNodeItem * nodeItem = ( SkeletonGraphicsNodeItem * ) item ;
const auto & find = nodeItemMap . find ( nodeItem - > id ( ) ) ;
2018-04-18 02:16:54 +00:00
if ( find = = nodeItemMap . end ( ) ) {
qDebug ( ) < < " Node item map key not found: " < < nodeItem - > id ( ) ;
return ;
}
checkSkeletonItem ( nodeItem , false ) ;
m_rangeSelectionSet . erase ( nodeItem ) ;
2022-10-18 09:35:04 +00:00
SkeletonGraphicsNodeItem * altNodeItem = nodeItem = = find - > second . first ? find - > second . second : find - > second . first ;
2018-04-18 02:16:54 +00:00
if ( checkSkeletonItem ( altNodeItem , true ) )
m_rangeSelectionSet . insert ( altNodeItem ) ;
} else if ( item - > data ( 0 ) = = " edge " ) {
2022-10-18 09:35:04 +00:00
SkeletonGraphicsEdgeItem * edgeItem = ( SkeletonGraphicsEdgeItem * ) item ;
const auto & find = edgeItemMap . find ( edgeItem - > id ( ) ) ;
2018-04-18 02:16:54 +00:00
if ( find = = edgeItemMap . end ( ) ) {
qDebug ( ) < < " Edge item map key not found: " < < edgeItem - > id ( ) ;
return ;
}
checkSkeletonItem ( edgeItem , false ) ;
m_rangeSelectionSet . erase ( edgeItem ) ;
2022-10-18 09:35:04 +00:00
SkeletonGraphicsEdgeItem * altEdgeItem = edgeItem = = find - > second . first ? find - > second . second : find - > second . first ;
2018-04-18 02:16:54 +00:00
if ( checkSkeletonItem ( altEdgeItem , true ) )
m_rangeSelectionSet . insert ( altEdgeItem ) ;
}
}
}
2018-04-21 00:23:27 +00:00
2022-10-18 09:35:04 +00:00
void SkeletonGraphicsWidget : : setItemHoveredOnAllProfiles ( QGraphicsItem * item , bool hovered )
2018-04-21 00:23:27 +00:00
{
if ( item - > data ( 0 ) = = " node " ) {
2022-10-18 09:35:04 +00:00
SkeletonGraphicsNodeItem * nodeItem = ( SkeletonGraphicsNodeItem * ) item ;
const auto & find = nodeItemMap . find ( nodeItem - > id ( ) ) ;
2018-04-21 00:23:27 +00:00
if ( find = = nodeItemMap . end ( ) ) {
qDebug ( ) < < " Node item map key not found: " < < nodeItem - > id ( ) ;
return ;
}
find - > second . first - > setHovered ( hovered ) ;
find - > second . second - > setHovered ( hovered ) ;
} else if ( item - > data ( 0 ) = = " edge " ) {
2022-10-18 09:35:04 +00:00
SkeletonGraphicsEdgeItem * edgeItem = ( SkeletonGraphicsEdgeItem * ) item ;
const auto & find = edgeItemMap . find ( edgeItem - > id ( ) ) ;
2018-04-21 00:23:27 +00:00
if ( find = = edgeItemMap . end ( ) ) {
qDebug ( ) < < " Edge item map key not found: " < < edgeItem - > id ( ) ;
return ;
}
find - > second . first - > setHovered ( hovered ) ;
find - > second . second - > setHovered ( hovered ) ;
}
}
2018-05-24 01:44:40 +00:00
void SkeletonGraphicsWidget : : ikMoveReady ( )
{
unsigned long long movedUpdateVersion = m_ikMover - > getUpdateVersion ( ) ;
2022-10-18 09:35:04 +00:00
if ( movedUpdateVersion = = m_ikMoveUpdateVersion & & ! m_ikMoveEndEffectorId . isNull ( ) ) {
2018-05-24 01:44:40 +00:00
emit batchChangeBegin ( ) ;
2022-10-18 09:35:04 +00:00
for ( const auto & it : m_ikMover - > ikNodes ( ) ) {
2019-10-19 13:14:36 +00:00
if ( m_rotated )
emit setNodeOrigin ( it . id , it . newPosition . y ( ) , it . newPosition . x ( ) , it . newPosition . z ( ) ) ;
else
emit setNodeOrigin ( it . id , it . newPosition . x ( ) , it . newPosition . y ( ) , it . newPosition . z ( ) ) ;
2018-05-24 01:44:40 +00:00
}
emit batchChangeEnd ( ) ;
emit groupOperationAdded ( ) ;
}
2022-10-18 09:35:04 +00:00
2018-05-24 01:44:40 +00:00
delete m_ikMover ;
m_ikMover = nullptr ;
2022-10-18 09:35:04 +00:00
if ( movedUpdateVersion ! = m_ikMoveUpdateVersion & & ! m_ikMoveEndEffectorId . isNull ( ) ) {
2018-05-24 01:44:40 +00:00
ikMove ( m_ikMoveEndEffectorId , m_ikMoveTarget ) ;
}
}
2018-04-21 00:23:27 +00:00
2021-11-18 14:58:01 +00:00
void SkeletonGraphicsWidget : : ikMove ( dust3d : : Uuid endEffectorId , QVector3D target )
2018-05-24 01:44:40 +00:00
{
m_ikMoveEndEffectorId = endEffectorId ;
m_ikMoveTarget = target ;
m_ikMoveUpdateVersion + + ;
if ( nullptr ! = m_ikMover ) {
return ;
}
2022-10-18 09:35:04 +00:00
QThread * thread = new QThread ;
2018-05-24 01:44:40 +00:00
m_ikMover = new SkeletonIkMover ( ) ;
m_ikMover - > setUpdateVersion ( m_ikMoveUpdateVersion ) ;
m_ikMover - > setTarget ( m_ikMoveTarget ) ;
2021-11-18 14:58:01 +00:00
dust3d : : Uuid nodeId = endEffectorId ;
std : : set < dust3d : : Uuid > historyNodeIds ;
std : : vector < std : : pair < dust3d : : Uuid , QVector3D > > appendNodes ;
2018-05-24 01:44:40 +00:00
for ( ; ; ) {
historyNodeIds . insert ( nodeId ) ;
const auto node = m_document - > findNode ( nodeId ) ;
if ( nullptr = = node )
break ;
2019-10-19 13:14:36 +00:00
appendNodes . push_back ( std : : make_pair ( nodeId , QVector3D ( node - > getX ( m_rotated ) , node - > getY ( m_rotated ) , node - > getZ ( m_rotated ) ) ) ) ;
2018-05-24 01:44:40 +00:00
if ( node - > edgeIds . size ( ) < 1 | | node - > edgeIds . size ( ) > 2 )
break ;
2021-11-18 14:58:01 +00:00
dust3d : : Uuid choosenNodeId ;
2022-10-18 09:35:04 +00:00
for ( const auto & edgeId : node - > edgeIds ) {
2018-05-24 01:44:40 +00:00
const auto edge = m_document - > findEdge ( edgeId ) ;
if ( nullptr = = edge )
break ;
2021-11-18 14:58:01 +00:00
dust3d : : Uuid neighborNodeId = edge - > neighborOf ( nodeId ) ;
2018-05-24 01:44:40 +00:00
if ( historyNodeIds . find ( neighborNodeId ) ! = historyNodeIds . end ( ) )
continue ;
choosenNodeId = neighborNodeId ;
break ;
}
if ( choosenNodeId . isNull ( ) )
break ;
nodeId = choosenNodeId ;
}
qDebug ( ) < < " ik move nodes: " ;
for ( int i = appendNodes . size ( ) - 1 ; i > = 0 ; i - - ) {
qDebug ( ) < < i < < appendNodes [ i ] . first < < appendNodes [ i ] . second ;
m_ikMover - > addNode ( appendNodes [ i ] . first , appendNodes [ i ] . second ) ;
}
qDebug ( ) < < " target: " < < m_ikMoveTarget ;
m_ikMover - > moveToThread ( thread ) ;
connect ( thread , & QThread : : started , m_ikMover , & SkeletonIkMover : : process ) ;
connect ( m_ikMover , & SkeletonIkMover : : finished , this , & SkeletonGraphicsWidget : : ikMoveReady ) ;
connect ( m_ikMover , & SkeletonIkMover : : finished , thread , & QThread : : quit ) ;
connect ( thread , & QThread : : finished , thread , & QThread : : deleteLater ) ;
thread - > start ( ) ;
}
2022-11-11 20:31:49 +00:00
void SkeletonGraphicsWidget : : setNodeBoneJointStates ( const std : : vector < dust3d : : Uuid > & 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 < SkeletonGraphicsNodeItem * > nodeItems ;
readMergedSkeletonNodeSetFromRangeSelection ( & nodeItems ) ;
if ( nodeItems . empty ( ) )
return ;
std : : vector < dust3d : : Uuid > nodeIds ;
for ( const auto & it : nodeItems ) {
nodeIds . push_back ( it - > id ( ) ) ;
}
setNodeBoneJointStates ( nodeIds , true ) ;
}
void SkeletonGraphicsWidget : : markSelectedAsNotBoneJoint ( )
{
std : : set < SkeletonGraphicsNodeItem * > nodeItems ;
readMergedSkeletonNodeSetFromRangeSelection ( & nodeItems ) ;
if ( nodeItems . empty ( ) )
return ;
std : : vector < dust3d : : Uuid > nodeIds ;
for ( const auto & it : nodeItems ) {
nodeIds . push_back ( it - > id ( ) ) ;
}
setNodeBoneJointStates ( nodeIds , false ) ;
}