2018-04-07 08:44:39 +00:00
# include <QDebug>
# include <QScrollBar>
# include <QGuiApplication>
# include <cmath>
# include <QtGlobal>
# include <algorithm>
2018-04-08 15:08:23 +00:00
# include <QVector2D>
2018-04-09 03:39:04 +00:00
# include <QMenu>
2018-04-09 08:46:06 +00:00
# include <QApplication>
2018-04-13 00:04:18 +00:00
# include <QMatrix4x4>
2018-12-11 11:55:55 +00:00
# include <queue>
2018-04-07 08:44:39 +00:00
# include "skeletongraphicswidget.h"
# include "theme.h"
2018-10-25 00:19:38 +00:00
# include "util.h"
# include "snapshotxml.h"
2018-09-14 09:45:05 +00:00
# include "markiconcreator.h"
2018-04-07 08:44:39 +00:00
2018-11-03 08:09:42 +00:00
SkeletonGraphicsWidget : : SkeletonGraphicsWidget ( const SkeletonDocument * document ) :
2018-04-07 08:44:39 +00:00
m_document ( document ) ,
2018-04-15 12:11:51 +00:00
m_backgroundItem ( nullptr ) ,
2018-04-07 08:44:39 +00:00
m_turnaroundChanged ( false ) ,
m_turnaroundLoader ( nullptr ) ,
m_dragStarted ( false ) ,
2018-04-15 12:11:51 +00:00
m_moveStarted ( false ) ,
2018-04-07 08:44:39 +00:00
m_cursorNodeItem ( nullptr ) ,
m_cursorEdgeItem ( nullptr ) ,
2018-04-08 15:08:23 +00:00
m_addFromNodeItem ( nullptr ) ,
2018-04-07 08:44:39 +00:00
m_hoveredNodeItem ( nullptr ) ,
m_hoveredEdgeItem ( nullptr ) ,
2018-04-15 12:11:51 +00:00
m_lastAddedX ( false ) ,
m_lastAddedY ( false ) ,
m_lastAddedZ ( false ) ,
2018-04-08 15:08:23 +00:00
m_selectionItem ( nullptr ) ,
m_rangeSelectionStarted ( false ) ,
2018-04-13 00:04:18 +00:00
m_mouseEventFromSelf ( false ) ,
2018-04-15 12:11:51 +00:00
m_moveHappened ( false ) ,
m_lastRot ( 0 ) ,
m_mainOriginItem ( nullptr ) ,
m_sideOriginItem ( nullptr ) ,
m_hoveredOriginItem ( nullptr ) ,
2018-05-24 01:44:40 +00:00
m_checkedOriginItem ( nullptr ) ,
m_ikMoveUpdateVersion ( 0 ) ,
2018-06-15 11:54:13 +00:00
m_ikMover ( nullptr ) ,
2018-10-24 08:54:18 +00:00
m_deferredRemoveTimer ( nullptr ) ,
m_eventForwardingToModelWidget ( false ) ,
2018-10-24 13:44:21 +00:00
m_modelWidget ( nullptr ) ,
m_inTempDragMode ( false ) ,
2018-11-05 15:47:21 +00:00
m_modeBeforeEnterTempDragMode ( SkeletonDocumentEditMode : : Select ) ,
2018-12-16 05:29:22 +00:00
m_nodePositionModifyOnly ( false ) ,
m_turnaroundOpacity ( 0.25 )
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 ) ;
setAlignment ( Qt : : AlignCenter ) ;
setScene ( new QGraphicsScene ( ) ) ;
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 ) ;
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 ) ;
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 ) ;
2018-04-08 15:08:23 +00:00
m_selectionItem = new SkeletonGraphicsSelectionItem ( ) ;
m_selectionItem - > hide ( ) ;
scene ( ) - > addItem ( m_selectionItem ) ;
2018-04-15 12:11:51 +00:00
m_mainOriginItem = new SkeletonGraphicsOriginItem ( SkeletonProfile : : Main ) ;
m_mainOriginItem - > hide ( ) ;
scene ( ) - > addItem ( m_mainOriginItem ) ;
m_sideOriginItem = new SkeletonGraphicsOriginItem ( SkeletonProfile : : Side ) ;
m_sideOriginItem - > hide ( ) ;
scene ( ) - > addItem ( m_sideOriginItem ) ;
2018-04-07 08:44:39 +00:00
scene ( ) - > setSceneRect ( rect ( ) ) ;
setMouseTracking ( true ) ;
2018-04-09 03:39:04 +00:00
setContextMenuPolicy ( Qt : : CustomContextMenu ) ;
connect ( this , & SkeletonGraphicsWidget : : customContextMenuRequested , this , & SkeletonGraphicsWidget : : showContextMenu ) ;
}
2018-10-24 08:54:18 +00:00
void SkeletonGraphicsWidget : : setModelWidget ( ModelWidget * modelWidget )
{
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 ) ;
}
2018-04-09 03:39:04 +00:00
void SkeletonGraphicsWidget : : showContextMenu ( const QPoint & pos )
{
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : Add = = m_document - > editMode ) {
emit setEditMode ( SkeletonDocumentEditMode : : Select ) ;
2018-04-09 03:39:04 +00:00
return ;
}
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : Select ! = m_document - > editMode ) {
2018-04-09 03:39:04 +00:00
return ;
}
QMenu contextMenu ( this ) ;
2018-04-10 07:59:20 +00:00
QAction addAction ( tr ( " Add... " ) , this ) ;
2018-11-05 15:47:21 +00:00
if ( ! m_nodePositionModifyOnly ) {
connect ( & addAction , & QAction : : triggered , [ = ] ( ) {
emit setEditMode ( SkeletonDocumentEditMode : : Add ) ;
} ) ;
contextMenu . addAction ( & addAction ) ;
}
2018-04-09 08:46:06 +00:00
2018-04-09 15:10:23 +00:00
QAction undoAction ( tr ( " Undo " ) , this ) ;
if ( m_document - > undoable ( ) ) {
2018-11-03 08:09:42 +00:00
connect ( & undoAction , & QAction : : triggered , m_document , & SkeletonDocument : : undo ) ;
2018-04-09 15:10:23 +00:00
contextMenu . addAction ( & undoAction ) ;
}
QAction redoAction ( tr ( " Redo " ) , this ) ;
if ( m_document - > redoable ( ) ) {
2018-11-03 08:09:42 +00:00
connect ( & redoAction , & QAction : : triggered , m_document , & SkeletonDocument : : redo ) ;
2018-04-09 15:10:23 +00:00
contextMenu . addAction ( & redoAction ) ;
}
QAction deleteAction ( tr ( " Delete " ) , this ) ;
2018-11-05 15:47:21 +00:00
if ( ! m_nodePositionModifyOnly & & hasSelection ( ) ) {
2018-04-09 14:37:20 +00:00
connect ( & deleteAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : deleteSelected ) ;
contextMenu . addAction ( & deleteAction ) ;
}
2018-04-09 08:46:06 +00:00
2018-04-12 12:27:21 +00:00
QAction breakAction ( tr ( " Break " ) , this ) ;
2018-11-05 15:47:21 +00:00
if ( ! m_nodePositionModifyOnly & & hasEdgeSelection ( ) ) {
2018-04-12 12:27:21 +00:00
connect ( & breakAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : breakSelected ) ;
contextMenu . addAction ( & breakAction ) ;
}
2018-04-12 12:46:13 +00:00
QAction connectAction ( tr ( " Connect " ) , this ) ;
2018-11-05 15:47:21 +00:00
if ( ! m_nodePositionModifyOnly & & hasTwoDisconnectedNodesSelection ( ) ) {
2018-04-12 12:46:13 +00:00
connect ( & connectAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : connectSelected ) ;
contextMenu . addAction ( & connectAction ) ;
}
2018-04-09 15:10:23 +00:00
QAction cutAction ( tr ( " Cut " ) , this ) ;
2018-11-05 15:47:21 +00:00
if ( ! m_nodePositionModifyOnly & & hasSelection ( ) ) {
2018-04-09 14:37:20 +00:00
connect ( & cutAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : cut ) ;
contextMenu . addAction ( & cutAction ) ;
}
2018-04-09 08:46:06 +00:00
2018-04-09 15:10:23 +00:00
QAction copyAction ( tr ( " Copy " ) , this ) ;
2018-11-09 03:20:48 +00:00
if ( hasNodeSelection ( ) ) {
2018-04-09 14:37:20 +00:00
connect ( & copyAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : copy ) ;
contextMenu . addAction ( & copyAction ) ;
}
2018-04-09 08:46:06 +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 ( ) ) {
2018-11-03 08:09:42 +00:00
connect ( & pasteAction , & QAction : : triggered , m_document , & SkeletonDocument : : paste ) ;
2018-04-09 14:37:20 +00:00
contextMenu . addAction ( & pasteAction ) ;
}
2018-04-09 03:39:04 +00:00
2018-04-09 15:10:23 +00:00
QAction flipHorizontallyAction ( tr ( " H Flip " ) , this ) ;
2018-11-05 15:47:21 +00:00
if ( ! m_nodePositionModifyOnly & & hasMultipleSelection ( ) ) {
2018-04-09 14:37:20 +00:00
connect ( & flipHorizontallyAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : flipHorizontally ) ;
contextMenu . addAction ( & flipHorizontallyAction ) ;
}
2018-04-09 14:24:30 +00:00
2018-04-09 15:10:23 +00:00
QAction flipVerticallyAction ( tr ( " V Flip " ) , this ) ;
2018-11-05 15:47:21 +00:00
if ( ! m_nodePositionModifyOnly & & hasMultipleSelection ( ) ) {
2018-04-09 14:37:20 +00:00
connect ( & flipVerticallyAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : flipVertically ) ;
contextMenu . addAction ( & flipVerticallyAction ) ;
}
2018-04-09 14:24:30 +00:00
2018-06-15 14:54:19 +00:00
QAction rotateClockwiseAction ( tr ( " Rotate 90D CW " ) , this ) ;
2018-11-05 15:47:21 +00:00
if ( ! m_nodePositionModifyOnly & & hasMultipleSelection ( ) ) {
2018-06-15 09:58:46 +00:00
connect ( & rotateClockwiseAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : rotateClockwise90Degree ) ;
contextMenu . addAction ( & rotateClockwiseAction ) ;
}
2018-06-15 14:54:19 +00:00
QAction rotateCounterclockwiseAction ( tr ( " Rotate 90D CCW " ) , this ) ;
2018-11-05 15:47:21 +00:00
if ( ! m_nodePositionModifyOnly & & hasMultipleSelection ( ) ) {
2018-06-15 09:58:46 +00:00
connect ( & rotateCounterclockwiseAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : rotateCounterclockwise90Degree ) ;
contextMenu . addAction ( & rotateCounterclockwiseAction ) ;
}
2018-06-21 08:24:18 +00:00
QAction switchXzAction ( tr ( " Switch XZ " ) , this ) ;
2018-11-05 15:47:21 +00:00
if ( ! m_nodePositionModifyOnly & & hasSelection ( ) ) {
2018-06-21 08:24:18 +00:00
connect ( & switchXzAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : switchSelectedXZ ) ;
contextMenu . addAction ( & switchXzAction ) ;
}
2018-11-09 23:56:58 +00:00
QAction switchChainSideAction ( tr ( " Switch Chain Side " ) , this ) ;
if ( m_nodePositionModifyOnly & & hasNodeSelection ( ) ) {
connect ( & switchChainSideAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : switchSelectedChainSide ) ;
contextMenu . addAction ( & switchChainSideAction ) ;
}
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 ) ;
2018-11-05 15:47:21 +00:00
if ( ! m_nodePositionModifyOnly & & ( ( hasSelection ( ) & & m_document - > originSettled ( ) ) | | hasMultipleSelection ( ) ) ) {
2018-06-02 09:34:48 +00:00
QMenu * subMenu = contextMenu . addMenu ( tr ( " Align To " ) ) ;
if ( hasMultipleSelection ( ) ) {
connect ( & alignToLocalCenterAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : alignSelectedToLocalCenter ) ;
subMenu - > addAction ( & alignToLocalCenterAction ) ;
connect ( & alignToLocalVerticalCenterAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : alignSelectedToLocalVerticalCenter ) ;
subMenu - > addAction ( & alignToLocalVerticalCenterAction ) ;
connect ( & alignToLocalHorizontalCenterAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : alignSelectedToLocalHorizontalCenter ) ;
subMenu - > addAction ( & alignToLocalHorizontalCenterAction ) ;
}
if ( hasSelection ( ) & & m_document - > originSettled ( ) ) {
connect ( & alignToGlobalCenterAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : alignSelectedToGlobalCenter ) ;
subMenu - > addAction ( & alignToGlobalCenterAction ) ;
connect ( & alignToGlobalVerticalCenterAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : alignSelectedToGlobalVerticalCenter ) ;
subMenu - > addAction ( & alignToGlobalVerticalCenterAction ) ;
connect ( & alignToGlobalHorizontalCenterAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : alignSelectedToGlobalHorizontalCenter ) ;
subMenu - > addAction ( & alignToGlobalHorizontalCenterAction ) ;
}
}
2018-04-16 07:12:53 +00:00
2018-09-14 09:45:05 +00:00
QAction markAsNoneAction ( tr ( " None " ) , this ) ;
2018-10-25 00:19:38 +00:00
QAction * markAsActions [ ( int ) BoneMark : : Count - 1 ] ;
for ( int i = 0 ; i < ( int ) BoneMark : : Count - 1 ; i + + ) {
2018-09-14 09:45:05 +00:00
markAsActions [ i ] = nullptr ;
}
2018-11-05 15:47:21 +00:00
if ( ! m_nodePositionModifyOnly & & hasNodeSelection ( ) ) {
2018-09-14 09:45:05 +00:00
QMenu * subMenu = contextMenu . addMenu ( tr ( " Mark As " ) ) ;
connect ( & markAsNoneAction , & QAction : : triggered , [ = ] ( ) {
2018-10-25 00:19:38 +00:00
setSelectedNodesBoneMark ( BoneMark : : None ) ;
2018-09-14 09:45:05 +00:00
} ) ;
subMenu - > addAction ( & markAsNoneAction ) ;
subMenu - > addSeparator ( ) ;
2018-10-25 00:19:38 +00:00
for ( int i = 0 ; i < ( int ) BoneMark : : Count - 1 ; i + + ) {
BoneMark boneMark = ( BoneMark ) ( i + 1 ) ;
markAsActions [ i ] = new QAction ( MarkIconCreator : : createIcon ( boneMark ) , BoneMarkToDispName ( boneMark ) , this ) ;
2018-09-14 09:45:05 +00:00
connect ( markAsActions [ i ] , & QAction : : triggered , [ = ] ( ) {
setSelectedNodesBoneMark ( boneMark ) ;
} ) ;
subMenu - > addAction ( markAsActions [ i ] ) ;
}
}
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 ) ;
}
2018-04-09 03:39:04 +00:00
2018-04-09 15:10:23 +00:00
QAction selectPartAllAction ( tr ( " Select Part " ) , this ) ;
2018-11-05 15:47:21 +00:00
if ( ! m_nodePositionModifyOnly & & hasItems ( ) ) {
2018-04-09 14:37:20 +00:00
connect ( & selectPartAllAction , & QAction : : triggered , this , & SkeletonGraphicsWidget : : selectPartAll ) ;
contextMenu . addAction ( & selectPartAllAction ) ;
}
2018-04-09 05:22:25 +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-09-14 09:45:05 +00:00
2018-10-25 00:19:38 +00:00
for ( int i = 0 ; i < ( int ) BoneMark : : Count - 1 ; i + + ) {
2018-09-14 09:45:05 +00:00
delete markAsActions [ i ] ;
}
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 ( )
{
for ( const auto & it : m_rangeSelectionSet ) {
if ( it - > data ( 0 ) = = " edge " )
return true ;
}
return false ;
}
2018-05-30 01:51:38 +00:00
bool SkeletonGraphicsWidget : : hasNodeSelection ( )
{
for ( const auto & it : m_rangeSelectionSet ) {
if ( it - > data ( 0 ) = = " node " )
return true ;
}
return false ;
}
2018-04-12 12:46:13 +00:00
bool SkeletonGraphicsWidget : : hasTwoDisconnectedNodesSelection ( )
{
std : : vector < QUuid > nodeIds ;
for ( const auto & it : m_rangeSelectionSet ) {
if ( it - > data ( 0 ) = = " node " ) {
nodeIds . push_back ( ( ( SkeletonGraphicsNodeItem * ) it ) - > id ( ) ) ;
}
}
if ( nodeIds . size ( ) ! = 2 )
return false ;
if ( m_document - > findEdgeByNodes ( nodeIds [ 0 ] , nodeIds [ 1 ] ) )
return false ;
return true ;
}
2018-04-12 12:27:21 +00:00
void SkeletonGraphicsWidget : : breakSelected ( )
{
std : : set < QUuid > edgeIds ;
for ( const auto & it : m_rangeSelectionSet ) {
if ( it - > data ( 0 ) = = " edge " )
edgeIds . insert ( ( ( SkeletonGraphicsEdgeItem * ) it ) - > id ( ) ) ;
}
2018-04-12 12:46:13 +00:00
if ( edgeIds . empty ( ) )
return ;
2018-04-12 12:27:21 +00:00
emit batchChangeBegin ( ) ;
for ( const auto & it : edgeIds ) {
emit breakEdge ( it ) ;
}
emit batchChangeEnd ( ) ;
2018-04-12 12:46:13 +00:00
emit groupOperationAdded ( ) ;
}
void SkeletonGraphicsWidget : : connectSelected ( )
{
std : : vector < QUuid > nodeIds ;
for ( const auto & it : m_rangeSelectionSet ) {
if ( it - > data ( 0 ) = = " node " ) {
nodeIds . push_back ( ( ( SkeletonGraphicsNodeItem * ) it ) - > id ( ) ) ;
}
}
if ( nodeIds . size ( ) ! = 2 )
return ;
if ( m_document - > findEdgeByNodes ( nodeIds [ 0 ] , nodeIds [ 1 ] ) )
return ;
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 ;
std : : set < SkeletonGraphicsNodeItem * > nodeItems ;
readMergedSkeletonNodeSetFromRangeSelection ( & nodeItems ) ;
if ( nodeItems . empty ( ) )
return ;
if ( nodeItems . size ( ) < 2 )
return ;
emit batchChangeBegin ( ) ;
QVector2D center = centerOfNodeItemSet ( nodeItems ) ;
for ( const auto & it : nodeItems ) {
SkeletonGraphicsNodeItem * nodeItem = it ;
QPointF nodeOrigin = nodeItem - > origin ( ) ;
float byX = alignToHorizontalCenter ? sceneRadiusToUnified ( center . x ( ) - nodeOrigin . x ( ) ) : 0 ;
float byY = alignToVerticalCenter ? sceneRadiusToUnified ( center . y ( ) - nodeOrigin . y ( ) ) : 0 ;
if ( SkeletonProfile : : Main = = nodeItem - > profile ( ) ) {
emit moveNodeBy ( nodeItem - > id ( ) , byX , byY , 0 ) ;
} else {
emit moveNodeBy ( nodeItem - > id ( ) , 0 , byY , byX ) ;
}
}
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 ;
std : : set < SkeletonGraphicsNodeItem * > nodeItems ;
readMergedSkeletonNodeSetFromRangeSelection ( & nodeItems ) ;
if ( nodeItems . empty ( ) )
return ;
emit batchChangeBegin ( ) ;
for ( const auto & nodeItem : nodeItems ) {
2018-11-03 08:09:42 +00:00
const SkeletonNode * node = m_document - > findNode ( nodeItem - > id ( ) ) ;
2018-04-16 07:12:53 +00:00
if ( ! node ) {
qDebug ( ) < < " Find node id failed: " < < nodeItem - > id ( ) ;
continue ;
}
if ( SkeletonProfile : : Main = = nodeItem - > profile ( ) ) {
2018-06-02 09:34:48 +00:00
if ( alignToVerticalCenter & & alignToHorizontalCenter ) {
emit moveNodeBy ( node - > id , m_document - > originX - node - > x , m_document - > originY - node - > y , 0 ) ;
} else if ( alignToVerticalCenter ) {
emit moveNodeBy ( node - > id , 0 , m_document - > originY - node - > y , 0 ) ;
} else if ( alignToHorizontalCenter ) {
emit moveNodeBy ( node - > id , m_document - > originX - node - > x , 0 , 0 ) ;
}
2018-04-16 07:12:53 +00:00
} else {
2018-06-02 09:34:48 +00:00
if ( alignToVerticalCenter & & alignToHorizontalCenter ) {
emit moveNodeBy ( node - > id , 0 , m_document - > originY - node - > y , m_document - > originZ - node - > z ) ;
} else if ( alignToVerticalCenter ) {
emit moveNodeBy ( node - > id , 0 , m_document - > originY - node - > y , 0 ) ;
} else if ( alignToHorizontalCenter ) {
emit moveNodeBy ( node - > id , 0 , 0 , m_document - > originZ - node - > z ) ;
}
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 ( )
{
2018-05-11 15:06:54 +00:00
const QImage * turnaroundImage = & m_document - > turnaround ;
QImage onePixel ( 16 , 10 , QImage : : Format_ARGB32 ) ;
if ( turnaroundImage - > isNull ( ) ) {
onePixel . fill ( Qt : : transparent ) ;
turnaroundImage = & onePixel ;
}
2018-04-07 08:44:39 +00:00
m_turnaroundChanged = true ;
if ( m_turnaroundLoader )
return ;
m_turnaroundChanged = false ;
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 ( )
{
QImage * backgroundImage = m_turnaroundLoader - > takeResultImage ( ) ;
if ( backgroundImage & & backgroundImage - > width ( ) > 0 & & backgroundImage - > height ( ) > 0 ) {
2018-08-27 08:50:40 +00:00
//qDebug() << "Fit turnaround finished with image size:" << backgroundImage->size();
2018-04-07 08:44:39 +00:00
setFixedSize ( backgroundImage - > size ( ) ) ;
scene ( ) - > setSceneRect ( rect ( ) ) ;
m_backgroundItem - > setPixmap ( QPixmap : : fromImage ( * backgroundImage ) ) ;
updateItems ( ) ;
} else {
qDebug ( ) < < " Fit turnaround failed " ;
}
delete backgroundImage ;
delete m_turnaroundLoader ;
m_turnaroundLoader = nullptr ;
if ( m_turnaroundChanged ) {
updateTurnaround ( ) ;
}
}
void SkeletonGraphicsWidget : : updateCursor ( )
{
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : Add ! = m_document - > editMode ) {
2018-04-07 08:44:39 +00:00
m_cursorEdgeItem - > hide ( ) ;
m_cursorNodeItem - > hide ( ) ;
}
switch ( m_document - > editMode ) {
2018-11-03 08:09:42 +00:00
case SkeletonDocumentEditMode : : Add :
2018-04-07 08:44:39 +00:00
setCursor ( QCursor ( Theme : : awesome ( ) - > icon ( fa : : plus ) . pixmap ( Theme : : toolIconFontSize , Theme : : toolIconFontSize ) ) ) ;
break ;
2018-11-03 08:09:42 +00:00
case SkeletonDocumentEditMode : : Select :
2018-04-08 15:08:23 +00:00
setCursor ( QCursor ( Theme : : awesome ( ) - > icon ( fa : : mousepointer ) . pixmap ( Theme : : toolIconFontSize , Theme : : toolIconFontSize ) , Theme : : toolIconFontSize / 5 , 0 ) ) ;
2018-04-07 08:44:39 +00:00
break ;
2018-11-03 08:09:42 +00:00
case SkeletonDocumentEditMode : : Drag :
2018-04-07 08:44:39 +00:00
setCursor ( QCursor ( Theme : : awesome ( ) - > icon ( m_dragStarted ? fa : : handrocko : fa : : handpapero ) . pixmap ( Theme : : toolIconFontSize , Theme : : toolIconFontSize ) ) ) ;
break ;
2018-11-03 08:09:42 +00:00
case SkeletonDocumentEditMode : : ZoomIn :
2018-04-07 08:44:39 +00:00
setCursor ( QCursor ( Theme : : awesome ( ) - > icon ( fa : : searchplus ) . pixmap ( Theme : : toolIconFontSize , Theme : : toolIconFontSize ) ) ) ;
break ;
2018-11-03 08:09:42 +00:00
case SkeletonDocumentEditMode : : ZoomOut :
2018-04-07 08:44:39 +00:00
setCursor ( QCursor ( Theme : : awesome ( ) - > icon ( fa : : searchminus ) . pixmap ( Theme : : toolIconFontSize , Theme : : toolIconFontSize ) ) ) ;
break ;
}
emit cursorChanged ( ) ;
}
void SkeletonGraphicsWidget : : editModeChanged ( )
{
2018-04-08 15:08:23 +00:00
updateCursor ( ) ;
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : Add = = m_document - > editMode ) {
2018-04-08 15:08:23 +00:00
SkeletonGraphicsNodeItem * choosenNodeItem = nullptr ;
if ( ! m_rangeSelectionSet . empty ( ) ) {
std : : set < SkeletonGraphicsNodeItem * > nodeItems ;
readMergedSkeletonNodeSetFromRangeSelection ( & nodeItems ) ;
if ( nodeItems . size ( ) = = 1 )
choosenNodeItem = * nodeItems . begin ( ) ;
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
}
}
void SkeletonGraphicsWidget : : mouseMoveEvent ( QMouseEvent * event )
{
2018-10-24 08:54:18 +00:00
if ( m_modelWidget & & m_modelWidget - > inputMouseMoveEventFromOtherWidget ( event ) )
return ;
2018-04-07 08:44:39 +00:00
QGraphicsView : : mouseMoveEvent ( event ) ;
mouseMove ( event ) ;
}
2018-11-15 14:33:56 +00:00
bool SkeletonGraphicsWidget : : inputWheelEventFromOtherWidget ( QWheelEvent * event )
{
if ( ! wheel ( event ) ) {
if ( m_modelWidget & & m_modelWidget - > inputWheelEventFromOtherWidget ( event ) )
return true ;
}
return true ;
}
2018-04-07 08:44:39 +00:00
void SkeletonGraphicsWidget : : wheelEvent ( QWheelEvent * event )
{
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
}
void SkeletonGraphicsWidget : : mouseReleaseEvent ( QMouseEvent * event )
{
2018-10-24 08:54:18 +00:00
if ( m_modelWidget & & m_modelWidget - > inputMouseReleaseEventFromOtherWidget ( event ) )
return ;
2018-04-07 08:44:39 +00:00
QGraphicsView : : mouseReleaseEvent ( event ) ;
mouseRelease ( event ) ;
}
void SkeletonGraphicsWidget : : mousePressEvent ( QMouseEvent * event )
{
2018-10-24 08:54:18 +00:00
if ( m_modelWidget & & m_modelWidget - > inputMousePressEventFromOtherWidget ( event ) )
return ;
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
}
void SkeletonGraphicsWidget : : mouseDoubleClickEvent ( QMouseEvent * event )
{
QGraphicsView : : mouseDoubleClickEvent ( event ) ;
mouseDoubleClick ( event ) ;
}
void SkeletonGraphicsWidget : : keyPressEvent ( QKeyEvent * event )
{
2018-08-29 15:42:04 +00:00
if ( keyPress ( event ) )
return ;
2018-04-07 08:44:39 +00:00
QGraphicsView : : keyPressEvent ( event ) ;
}
2018-10-24 13:44:21 +00:00
void SkeletonGraphicsWidget : : keyReleaseEvent ( QKeyEvent * event )
{
if ( keyRelease ( event ) )
return ;
QGraphicsView : : keyReleaseEvent ( event ) ;
}
2018-04-07 08:44:39 +00:00
bool SkeletonGraphicsWidget : : mouseMove ( QMouseEvent * event )
{
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 ;
}
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : 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 ;
}
}
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : Select = = m_document - > editMode | |
SkeletonDocumentEditMode : : Add = = m_document - > editMode ) {
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
//
2018-04-07 08:44:39 +00:00
SkeletonGraphicsNodeItem * newHoverNodeItem = nullptr ;
SkeletonGraphicsEdgeItem * newHoverEdgeItem = nullptr ;
2018-04-15 12:11:51 +00:00
SkeletonGraphicsOriginItem * newHoverOriginItem = nullptr ;
2018-04-20 07:38:08 +00:00
QPointF scenePos = mouseEventScenePos ( event ) ;
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 + + ) {
QGraphicsItem * item = * it ;
if ( item - > data ( 0 ) = = " node " ) {
2018-04-20 07:38:08 +00:00
SkeletonGraphicsNodeItem * nodeItem = ( SkeletonGraphicsNodeItem * ) item ;
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 " ) {
2018-04-20 07:38:08 +00:00
SkeletonGraphicsEdgeItem * edgeItem = ( SkeletonGraphicsEdgeItem * ) item ;
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 " ) {
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 ( ) ,
[ ] ( const std : : pair < QGraphicsItem * , float > & a , const std : : pair < QGraphicsItem * , float > & b ) {
return a . second < b . second ;
} ) ;
QGraphicsItem * pickedNearestItem = itemDistance2MapWithMouse [ 0 ] . first ;
if ( pickedNearestItem - > data ( 0 ) = = " node " ) {
newHoverNodeItem = ( SkeletonGraphicsNodeItem * ) pickedNearestItem ;
} else if ( pickedNearestItem - > data ( 0 ) = = " edge " ) {
newHoverEdgeItem = ( SkeletonGraphicsEdgeItem * ) pickedNearestItem ;
}
}
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 ) ;
}
}
2018-04-18 01:49:23 +00:00
QUuid 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
}
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : Add = = m_document - > editMode ) {
2018-04-07 08:44:39 +00:00
QPointF mouseScenePos = mouseEventScenePos ( event ) ;
m_cursorNodeItem - > setOrigin ( mouseScenePos ) ;
if ( ! m_cursorNodeItem - > isVisible ( ) ) {
m_cursorNodeItem - > show ( ) ;
}
2018-04-08 15:08:23 +00:00
if ( m_addFromNodeItem ) {
m_cursorEdgeItem - > setEndpoints ( m_addFromNodeItem , m_cursorNodeItem ) ;
2018-04-07 08:44:39 +00:00
if ( ! m_cursorEdgeItem - > isVisible ( ) ) {
m_cursorEdgeItem - > show ( ) ;
}
}
return true ;
}
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : 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 ) ) {
2018-05-24 01:44:40 +00:00
std : : set < SkeletonGraphicsNodeItem * > nodeItems ;
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 ) {
auto & nodeItem = * nodeItems . begin ( ) ;
2018-11-03 08:09:42 +00:00
const SkeletonNode * 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 ) ;
QVector3D target = QVector3D ( node - > x , node - > y , node - > z ) ;
if ( SkeletonProfile : : Main = = nodeItem - > profile ( ) ) {
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
}
}
}
return false ;
}
2018-04-13 01:27:28 +00:00
void SkeletonGraphicsWidget : : rotateSelected ( int degree )
{
if ( m_rangeSelectionSet . empty ( ) )
return ;
std : : set < SkeletonGraphicsNodeItem * > nodeItems ;
readMergedSkeletonNodeSetFromRangeSelection ( & nodeItems ) ;
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
QVector3D worldOrigin = QVector3D ( m_document - > originX , m_document - > originY , m_document - > originZ ) ;
SkeletonGraphicsNodeItem * centerNodeItem = * nodeItems . begin ( ) ;
const auto & centerNode = m_document - > findNode ( centerNodeItem - > id ( ) ) ;
if ( nullptr = = centerNode ) {
qDebug ( ) < < " findNode: " < < centerNodeItem - > id ( ) < < " failed while rotate " ;
return ;
}
std : : vector < std : : pair < QUuid , float > > directNeighborDists ;
for ( const auto & neighborId : centerNode - > edgeIds ) {
const auto & neighborEdge = m_document - > findEdge ( neighborId ) ;
if ( nullptr = = neighborEdge ) {
qDebug ( ) < < " findEdge: " < < neighborId < < " failed while rotate " ;
continue ;
}
const auto & neighborNodeId = neighborEdge - > neighborOf ( centerNodeItem - > id ( ) ) ;
const auto & neighborNode = m_document - > findNode ( neighborNodeId ) ;
if ( nullptr = = centerNode ) {
qDebug ( ) < < " findNode: " < < neighborNodeId < < " failed while rotate " ;
continue ;
}
QVector3D nodeOrigin ( neighborNode - > x , neighborNode - > y , neighborNode - > z ) ;
directNeighborDists . push_back ( std : : make_pair ( neighborNodeId , ( nodeOrigin - worldOrigin ) . lengthSquared ( ) ) ) ;
}
std : : sort ( directNeighborDists . begin ( ) , directNeighborDists . end ( ) , [ ] ( const std : : pair < QUuid , float > & a , const std : : pair < QUuid , float > & b ) {
return a . second < b . second ;
} ) ;
int skippedNum = 1 ;
if ( directNeighborDists . size ( ) = = 1 ) {
skippedNum = 0 ;
}
std : : set < QUuid > neighborIds ;
// 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 ( ) ;
for ( const auto & neighborId : neighborIds ) {
const auto & findItemResult = nodeItemMap . find ( neighborId ) ;
if ( findItemResult = = nodeItemMap . end ( ) ) {
qDebug ( ) < < " find node item: " < < neighborId < < " failed " ;
continue ;
}
if ( SkeletonProfile : : Main = = centerNodeItem - > profile ( ) ) {
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 ) ;
}
void SkeletonGraphicsWidget : : rotateItems ( const std : : set < SkeletonGraphicsNodeItem * > & nodeItems , int degree , QVector2D center )
{
emit disableAllPositionRelatedLocks ( ) ;
QVector3D centerPoint ( center . x ( ) , center . y ( ) , 0 ) ;
qNormalizeAngle ( degree ) ;
2018-04-13 01:27:28 +00:00
for ( const auto & it : nodeItems ) {
SkeletonGraphicsNodeItem * nodeItem = it ;
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 ( ) ) ;
if ( SkeletonProfile : : Main = = nodeItem - > profile ( ) ) {
emit moveNodeBy ( nodeItem - > id ( ) , byX , byY , 0 ) ;
} else {
emit moveNodeBy ( nodeItem - > id ( ) , 0 , byY , byX ) ;
}
}
2018-09-03 07:05:05 +00:00
emit enableAllPositionRelatedLocks ( ) ;
}
void SkeletonGraphicsWidget : : rotateAllSideProfile ( int degree )
{
std : : set < SkeletonGraphicsNodeItem * > items ;
for ( const auto & item : nodeItemMap ) {
items . insert ( item . second . second ) ;
}
QVector2D center ( scenePosFromUnified ( QPointF ( m_document - > originZ , m_document - > originY ) ) ) ;
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 ) ;
if ( SkeletonProfile : : Main = = m_checkedOriginItem - > profile ( ) ) {
emit moveOriginBy ( byX , byY , 0 ) ;
} else {
emit moveOriginBy ( 0 , byY , byX ) ;
}
}
2018-04-13 01:27:28 +00:00
void SkeletonGraphicsWidget : : moveSelected ( float byX , float byY )
{
if ( m_rangeSelectionSet . empty ( ) )
return ;
2018-05-24 01:44:40 +00:00
m_ikMoveEndEffectorId = QUuid ( ) ;
2018-04-13 01:27:28 +00:00
byX = sceneRadiusToUnified ( byX ) ;
byY = sceneRadiusToUnified ( byY ) ;
std : : set < SkeletonGraphicsNodeItem * > nodeItems ;
readMergedSkeletonNodeSetFromRangeSelection ( & nodeItems ) ;
for ( const auto & it : nodeItems ) {
SkeletonGraphicsNodeItem * nodeItem = it ;
if ( SkeletonProfile : : Main = = nodeItem - > profile ( ) ) {
emit moveNodeBy ( nodeItem - > id ( ) , byX , byY , 0 ) ;
} else {
emit moveNodeBy ( nodeItem - > id ( ) , 0 , byY , byX ) ;
}
}
}
2018-06-21 08:24:18 +00:00
void SkeletonGraphicsWidget : : switchSelectedXZ ( )
{
if ( m_rangeSelectionSet . empty ( ) )
return ;
std : : set < QUuid > nodeIdSet ;
readSkeletonNodeAndEdgeIdSetFromRangeSelection ( & nodeIdSet ) ;
if ( nodeIdSet . empty ( ) )
return ;
emit batchChangeBegin ( ) ;
for ( const auto nodeId : nodeIdSet ) {
emit switchNodeXZ ( nodeId ) ;
}
emit batchChangeEnd ( ) ;
emit groupOperationAdded ( ) ;
}
2018-11-09 23:56:58 +00:00
void SkeletonGraphicsWidget : : switchSelectedChainSide ( )
{
if ( m_rangeSelectionSet . empty ( ) )
return ;
std : : set < QUuid > nodeIdSet ;
readSkeletonNodeAndEdgeIdSetFromRangeSelection ( & nodeIdSet ) ;
if ( nodeIdSet . empty ( ) )
return ;
emit switchChainSide ( nodeIdSet ) ;
emit groupOperationAdded ( ) ;
}
2018-04-13 01:27:28 +00:00
void SkeletonGraphicsWidget : : zoomSelected ( float delta )
{
if ( m_rangeSelectionSet . empty ( ) )
return ;
std : : set < SkeletonGraphicsNodeItem * > nodeItems ;
readMergedSkeletonNodeSetFromRangeSelection ( & nodeItems ) ;
float unifiedDelta = sceneRadiusToUnified ( delta ) ;
for ( const auto & it : nodeItems ) {
SkeletonGraphicsNodeItem * nodeItem = it ;
emit scaleNodeByAddRadius ( nodeItem - > id ( ) , unifiedDelta ) ;
}
}
void SkeletonGraphicsWidget : : scaleSelected ( float delta )
{
if ( m_rangeSelectionSet . empty ( ) )
return ;
std : : set < SkeletonGraphicsNodeItem * > nodeItems ;
readMergedSkeletonNodeSetFromRangeSelection ( & nodeItems ) ;
QVector2D center = centerOfNodeItemSet ( nodeItems ) ;
for ( const auto & nodeItem : nodeItems ) {
QVector2D origin = QVector2D ( nodeItem - > origin ( ) ) ;
QVector2D ray = ( center - origin ) * 0.01 * delta ;
float byX = - sceneRadiusToUnified ( ray . x ( ) ) ;
float byY = - sceneRadiusToUnified ( ray . y ( ) ) ;
if ( SkeletonProfile : : Main = = nodeItem - > profile ( ) ) {
emit moveNodeBy ( nodeItem - > id ( ) , byX , byY , 0 ) ;
} else {
emit moveNodeBy ( nodeItem - > id ( ) , 0 , byY , byX ) ;
}
}
}
2018-04-07 08:44:39 +00:00
bool SkeletonGraphicsWidget : : wheel ( QWheelEvent * event )
{
qreal delta = event - > delta ( ) / 10 ;
if ( QGuiApplication : : queryKeyboardModifiers ( ) . testFlag ( Qt : : ShiftModifier ) ) {
if ( delta > 0 )
delta = 1 ;
else
delta = - 1 ;
} else {
if ( fabs ( delta ) < 1 )
delta = delta < 0 ? - 1.0 : 1.0 ;
}
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : 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 ;
}
2018-11-03 08:09:42 +00:00
} else if ( SkeletonDocumentEditMode : : 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 ;
}
2018-04-09 14:24:30 +00:00
QVector2D SkeletonGraphicsWidget : : centerOfNodeItemSet ( const std : : set < SkeletonGraphicsNodeItem * > & set )
{
QVector2D center ;
for ( const auto & nodeItem : set ) {
center + = QVector2D ( nodeItem - > origin ( ) ) ;
}
center / = set . size ( ) ;
return center ;
}
void SkeletonGraphicsWidget : : flipHorizontally ( )
{
std : : set < SkeletonGraphicsNodeItem * > nodeItems ;
readMergedSkeletonNodeSetFromRangeSelection ( & nodeItems ) ;
if ( nodeItems . empty ( ) )
return ;
QVector2D center = centerOfNodeItemSet ( nodeItems ) ;
2018-06-15 09:58:46 +00:00
emit batchChangeBegin ( ) ;
2018-04-09 14:24:30 +00:00
for ( const auto & nodeItem : nodeItems ) {
QPointF origin = nodeItem - > origin ( ) ;
float offset = origin . x ( ) - center . x ( ) ;
float unifiedOffset = - sceneRadiusToUnified ( offset * 2 ) ;
if ( SkeletonProfile : : Main = = nodeItem - > profile ( ) ) {
emit moveNodeBy ( nodeItem - > id ( ) , unifiedOffset , 0 , 0 ) ;
} 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 ( )
{
std : : set < SkeletonGraphicsNodeItem * > nodeItems ;
readMergedSkeletonNodeSetFromRangeSelection ( & nodeItems ) ;
if ( nodeItems . empty ( ) )
return ;
QVector2D center = centerOfNodeItemSet ( nodeItems ) ;
2018-06-15 09:58:46 +00:00
emit batchChangeBegin ( ) ;
2018-04-09 14:24:30 +00:00
for ( const auto & nodeItem : nodeItems ) {
QPointF origin = nodeItem - > origin ( ) ;
float offset = origin . y ( ) - center . y ( ) ;
float unifiedOffset = - sceneRadiusToUnified ( offset * 2 ) ;
emit moveNodeBy ( nodeItem - > id ( ) , 0 , unifiedOffset , 0 ) ;
}
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 ( ) ;
}
2018-04-07 08:44:39 +00:00
bool SkeletonGraphicsWidget : : mouseRelease ( QMouseEvent * event )
{
if ( event - > button ( ) = = Qt : : LeftButton ) {
2018-04-08 15:08:23 +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 ;
}
QPointF SkeletonGraphicsWidget : : mouseEventScenePos ( QMouseEvent * event )
{
return mapToScene ( mapFromGlobal ( event - > globalPos ( ) ) ) ;
}
bool SkeletonGraphicsWidget : : mousePress ( QMouseEvent * event )
{
if ( event - > button ( ) = = Qt : : LeftButton ) {
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : 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 ) ;
2018-04-07 08:44:39 +00:00
scale ( 1.5 , 1.5 ) ;
setTransformationAnchor ( lastAnchor ) ;
return true ;
2018-11-03 08:09:42 +00:00
} else if ( SkeletonDocumentEditMode : : 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 ) ;
2018-04-07 08:44:39 +00:00
scale ( 0.5 , 0.5 ) ;
setTransformationAnchor ( lastAnchor ) ;
if ( ( ! verticalScrollBar ( ) | | ! verticalScrollBar ( ) - > isVisible ( ) ) & &
( ! horizontalScrollBar ( ) | | ! horizontalScrollBar ( ) - > isVisible ( ) ) ) {
setTransform ( QTransform ( ) ) ;
}
return true ;
2018-11-03 08:09:42 +00:00
} else if ( SkeletonDocumentEditMode : : Drag = = m_document - > editMode ) {
2018-04-07 08:44:39 +00:00
if ( ! m_dragStarted ) {
m_lastGlobalPos = event - > globalPos ( ) ;
m_dragStarted = true ;
updateCursor ( ) ;
}
2018-11-03 08:09:42 +00:00
} else if ( SkeletonDocumentEditMode : : 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 ) {
if ( m_hoveredNodeItem & & m_addFromNodeItem & &
m_hoveredNodeItem ! = m_addFromNodeItem & &
2018-09-01 23:48:38 +00:00
m_hoveredNodeItem - > profile ( ) = = m_addFromNodeItem - > profile ( ) & &
! m_document - > findEdgeByNodes ( m_addFromNodeItem - > id ( ) , m_hoveredNodeItem - > id ( ) ) & &
m_document - > isNodeEditable ( m_hoveredNodeItem - > id ( ) ) ) {
2018-04-08 15:08:23 +00:00
emit addEdge ( m_addFromNodeItem - > id ( ) , m_hoveredNodeItem - > id ( ) ) ;
2018-04-08 23:34:46 +00:00
emit groupOperationAdded ( ) ;
2018-04-07 08:44:39 +00:00
return true ;
}
}
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 ( ) ) ;
2018-04-10 08:44:02 +00:00
if ( SkeletonProfile : : Main = = m_addFromNodeItem - > profile ( ) )
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 {
sideProfile . setX ( mainProfile . x ( ) + scene ( ) - > width ( ) / 4 ) ;
}
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 ( ) ;
2018-04-08 15:08:23 +00:00
emit addNode ( unifiedMainPos . x ( ) , unifiedMainPos . y ( ) , unifiedSidePos . x ( ) , sceneRadiusToUnified ( m_cursorNodeItem - > radius ( ) ) , nullptr = = m_addFromNodeItem ? QUuid ( ) : m_addFromNodeItem - > id ( ) ) ;
2018-04-08 23:34:46 +00:00
emit groupOperationAdded ( ) ;
2018-04-07 08:44:39 +00:00
return true ;
}
2018-11-03 08:09:42 +00:00
} else if ( SkeletonDocumentEditMode : : 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 {
2018-04-12 14:35:50 +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
}
}
2018-04-11 15:06:30 +00:00
if ( event - > button ( ) = = Qt : : LeftButton ) {
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : 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 ;
}
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 ( ) ) ;
}
bool SkeletonGraphicsWidget : : mouseDoubleClick ( QMouseEvent * event )
{
2018-04-09 11:13:34 +00:00
if ( m_hoveredNodeItem | | m_hoveredEdgeItem ) {
2018-12-11 11:55:55 +00:00
if ( m_nodePositionModifyOnly )
selectConnectedAll ( ) ;
else
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 ;
bool committed = false ;
if ( ! committed & & ! m_deferredRemoveEdgeIds . empty ( ) ) {
const auto & it = m_deferredRemoveEdgeIds . begin ( ) ;
const auto edgeId = * it ;
m_deferredRemoveEdgeIds . erase ( it ) ;
emit removeEdge ( edgeId ) ;
committed = true ;
}
if ( ! committed & & ! m_deferredRemoveNodeIds . empty ( ) ) {
const auto & it = m_deferredRemoveNodeIds . begin ( ) ;
const auto nodeId = * it ;
m_deferredRemoveNodeIds . erase ( it ) ;
emit removeNode ( nodeId ) ;
committed = true ;
}
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 ;
std : : set < QUuid > nodeIdSet ;
std : : set < QUuid > edgeIdSet ;
readSkeletonNodeAndEdgeIdSetFromRangeSelection ( & nodeIdSet , & edgeIdSet ) ;
for ( const auto & it : nodeIdSet ) {
m_deferredRemoveNodeIds . insert ( it ) ;
}
for ( const auto & it : edgeIdSet ) {
m_deferredRemoveEdgeIds . insert ( it ) ;
}
if ( nullptr = = m_deferredRemoveTimer ) {
timeToRemoveDeferredNodesAndEdges ( ) ;
}
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
{
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 ( )
{
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : Add = = m_document - > editMode ) {
emit setEditMode ( SkeletonDocumentEditMode : : Select ) ;
2018-10-24 13:44:21 +00:00
} else {
2018-11-03 08:09:42 +00:00
emit setEditMode ( SkeletonDocumentEditMode : : Add ) ;
2018-10-24 13:44:21 +00:00
}
}
void SkeletonGraphicsWidget : : shortcutUndo ( )
{
emit undo ( ) ;
}
void SkeletonGraphicsWidget : : shortcutRedo ( )
{
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 ( )
{
cut ( ) ;
}
void SkeletonGraphicsWidget : : shortcutCopy ( )
{
copy ( ) ;
}
void SkeletonGraphicsWidget : : shortcutPaste ( )
{
emit paste ( ) ;
}
void SkeletonGraphicsWidget : : shortcutSave ( )
{
emit save ( ) ;
}
void SkeletonGraphicsWidget : : shortcutSelectMode ( )
{
2018-11-03 08:09:42 +00:00
emit setEditMode ( SkeletonDocumentEditMode : : Select ) ;
2018-10-24 13:44:21 +00:00
}
void SkeletonGraphicsWidget : : shortcutDragMode ( )
{
2018-11-03 08:09:42 +00:00
emit setEditMode ( SkeletonDocumentEditMode : : Drag ) ;
2018-10-24 13:44:21 +00:00
}
void SkeletonGraphicsWidget : : shortcutZoomRenderedModelByMinus10 ( )
{
emit zoomRenderedModelBy ( - 10 ) ;
}
void SkeletonGraphicsWidget : : shortcutZoomSelectedByMinus1 ( )
{
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : Select = = m_document - > editMode & & hasSelection ( ) ) {
2018-10-24 13:44:21 +00:00
zoomSelected ( - 1 ) ;
emit groupOperationAdded ( ) ;
2018-12-15 13:41:02 +00:00
} else if ( SkeletonDocumentEditMode : : Add = = m_document - > editMode ) {
if ( m_cursorNodeItem - > isVisible ( ) ) {
m_cursorNodeItem - > setRadius ( m_cursorNodeItem - > radius ( ) + - 1 ) ;
}
2018-10-24 13:44:21 +00:00
}
}
void SkeletonGraphicsWidget : : shortcutZoomRenderedModelBy10 ( )
{
emit zoomRenderedModelBy ( 10 ) ;
}
void SkeletonGraphicsWidget : : shortcutZoomSelectedBy1 ( )
{
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : Select = = m_document - > editMode & & hasSelection ( ) ) {
2018-10-24 13:44:21 +00:00
zoomSelected ( 1 ) ;
emit groupOperationAdded ( ) ;
2018-12-15 13:41:02 +00:00
} else if ( SkeletonDocumentEditMode : : Add = = m_document - > editMode ) {
if ( m_cursorNodeItem - > isVisible ( ) ) {
m_cursorNodeItem - > setRadius ( m_cursorNodeItem - > radius ( ) + 1 ) ;
}
2018-10-24 13:44:21 +00:00
}
}
void SkeletonGraphicsWidget : : shortcutRotateSelectedByMinus1 ( )
{
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : Select = = m_document - > editMode & & hasSelection ( ) ) {
2018-10-24 13:44:21 +00:00
rotateSelected ( - 1 ) ;
emit groupOperationAdded ( ) ;
}
}
void SkeletonGraphicsWidget : : shortcutRotateSelectedBy1 ( )
{
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : Select = = m_document - > editMode & & hasSelection ( ) ) {
2018-10-24 13:44:21 +00:00
rotateSelected ( 1 ) ;
emit groupOperationAdded ( ) ;
}
}
void SkeletonGraphicsWidget : : shortcutMoveSelectedToLeft ( )
{
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : 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 ( )
{
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : 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 ( )
{
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : 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 ( )
{
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : 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 ( )
{
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : Select = = m_document - > editMode & & hasSelection ( ) ) {
2018-10-24 13:44:21 +00:00
scaleSelected ( - 1 ) ;
emit groupOperationAdded ( ) ;
}
}
void SkeletonGraphicsWidget : : shortcutScaleSelectedBy1 ( )
{
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : Select = = m_document - > editMode & & hasSelection ( ) ) {
2018-10-24 13:44:21 +00:00
scaleSelected ( 1 ) ;
emit groupOperationAdded ( ) ;
}
}
void SkeletonGraphicsWidget : : shortcutSwitchProfileOnSelected ( )
{
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : Select = = m_document - > editMode & & hasSelection ( ) ) {
2018-10-24 13:44:21 +00:00
switchProfileOnRangeSelection ( ) ;
}
}
void SkeletonGraphicsWidget : : shortcutShowOrHideSelectedPart ( )
{
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : Select = = m_document - > editMode & & ! m_lastCheckedPart . isNull ( ) ) {
const SkeletonPart * part = m_document - > findPart ( m_lastCheckedPart ) ;
2018-10-24 13:44:21 +00:00
bool partVisible = part & & part - > visible ;
emit setPartVisibleState ( m_lastCheckedPart , ! partVisible ) ;
emit groupOperationAdded ( ) ;
}
}
void SkeletonGraphicsWidget : : shortcutEnableOrDisableSelectedPart ( )
{
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : Select = = m_document - > editMode & & ! m_lastCheckedPart . isNull ( ) ) {
const SkeletonPart * 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 ( )
{
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : Select = = m_document - > editMode & & ! m_lastCheckedPart . isNull ( ) ) {
const SkeletonPart * 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 ( )
{
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : Select = = m_document - > editMode & & ! m_lastCheckedPart . isNull ( ) ) {
const SkeletonPart * 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 ( )
{
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : Select = = m_document - > editMode & & ! m_lastCheckedPart . isNull ( ) ) {
const SkeletonPart * 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 ( ) ;
}
}
void SkeletonGraphicsWidget : : shortcutRoundEndOrNotSelectedPart ( )
{
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : Select = = m_document - > editMode & & ! m_lastCheckedPart . isNull ( ) ) {
const SkeletonPart * 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 ( ) ;
}
}
bool SkeletonGraphicsWidget : : keyPress ( QKeyEvent * event )
{
if ( event - > key ( ) = = Qt : : Key_Space ) {
2018-11-03 08:09:42 +00:00
if ( SkeletonDocumentEditMode : : ZoomIn = = m_document - > editMode | |
SkeletonDocumentEditMode : : ZoomOut = = m_document - > editMode | |
SkeletonDocumentEditMode : : Select = = m_document - > editMode | |
SkeletonDocumentEditMode : : Add = = m_document - > editMode ) {
2018-10-24 13:44:21 +00:00
m_inTempDragMode = true ;
m_modeBeforeEnterTempDragMode = m_document - > editMode ;
2018-11-03 08:09:42 +00:00
emit setEditMode ( SkeletonDocumentEditMode : : 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
}
return false ;
}
bool SkeletonGraphicsWidget : : keyRelease ( QKeyEvent * event )
{
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
}
2018-10-24 13:44:21 +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 ;
}
m_mainOriginItem - > setOrigin ( scenePosFromUnified ( QPointF ( m_document - > originX , m_document - > originY ) ) ) ;
m_sideOriginItem - > setOrigin ( scenePosFromUnified ( QPointF ( m_document - > originZ , m_document - > originY ) ) ) ;
m_mainOriginItem - > show ( ) ;
m_sideOriginItem - > show ( ) ;
}
2018-04-07 08:44:39 +00:00
void SkeletonGraphicsWidget : : nodeAdded ( QUuid nodeId )
{
2018-11-03 08:09:42 +00:00
const SkeletonNode * 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 ;
}
2018-10-25 00:19:38 +00:00
QColor markColor = BoneMarkToColor ( node - > boneMark ) ;
2018-04-07 08:44:39 +00:00
SkeletonGraphicsNodeItem * mainProfileItem = new SkeletonGraphicsNodeItem ( SkeletonProfile : : Main ) ;
SkeletonGraphicsNodeItem * sideProfileItem = new SkeletonGraphicsNodeItem ( SkeletonProfile : : Side ) ;
mainProfileItem - > setOrigin ( scenePosFromUnified ( QPointF ( node - > x , node - > y ) ) ) ;
sideProfileItem - > setOrigin ( scenePosFromUnified ( QPointF ( node - > z , node - > y ) ) ) ;
mainProfileItem - > setRadius ( sceneRadiusFromUnified ( node - > radius ) ) ;
sideProfileItem - > setRadius ( sceneRadiusFromUnified ( node - > radius ) ) ;
2018-09-14 09:45:05 +00:00
mainProfileItem - > setMarkColor ( markColor ) ;
sideProfileItem - > setMarkColor ( markColor ) ;
2018-04-07 08:44:39 +00:00
mainProfileItem - > setId ( nodeId ) ;
sideProfileItem - > setId ( nodeId ) ;
scene ( ) - > addItem ( mainProfileItem ) ;
scene ( ) - > addItem ( sideProfileItem ) ;
nodeItemMap [ nodeId ] = std : : make_pair ( mainProfileItem , sideProfileItem ) ;
2018-04-08 15:08:23 +00:00
if ( nullptr = = m_addFromNodeItem ) {
m_addFromNodeItem = mainProfileItem ;
2018-04-07 08:44:39 +00:00
} else {
2018-04-08 15:08:23 +00:00
if ( SkeletonProfile : : Main = = m_addFromNodeItem - > profile ( ) ) {
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
}
}
void SkeletonGraphicsWidget : : edgeAdded ( QUuid edgeId )
{
2018-11-03 08:09:42 +00:00
const SkeletonEdge * 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 ;
}
QUuid fromNodeId = edge - > nodeIds [ 0 ] ;
QUuid toNodeId = edge - > nodeIds [ 1 ] ;
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 ;
}
2018-04-07 08:44:39 +00:00
SkeletonGraphicsEdgeItem * mainProfileEdgeItem = new SkeletonGraphicsEdgeItem ( ) ;
SkeletonGraphicsEdgeItem * sideProfileEdgeItem = new SkeletonGraphicsEdgeItem ( ) ;
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 ) ;
}
2018-04-08 15:08:23 +00:00
void SkeletonGraphicsWidget : : removeItem ( QGraphicsItem * item )
{
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 ) ;
}
2018-04-07 08:44:39 +00:00
void SkeletonGraphicsWidget : : nodeRemoved ( QUuid nodeId )
{
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 ) ;
}
void SkeletonGraphicsWidget : : edgeRemoved ( QUuid edgeId )
{
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 ) ;
}
void SkeletonGraphicsWidget : : nodeRadiusChanged ( QUuid nodeId )
{
2018-11-03 08:09:42 +00:00
const SkeletonNode * 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 ) ;
}
2018-09-14 09:45:05 +00:00
void SkeletonGraphicsWidget : : nodeBoneMarkChanged ( QUuid nodeId )
{
2018-11-03 08:09:42 +00:00
const SkeletonNode * node = m_document - > findNode ( nodeId ) ;
2018-09-14 09:45:05 +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 ;
}
2018-10-25 00:19:38 +00:00
QColor markColor = BoneMarkToColor ( node - > boneMark ) ;
2018-09-14 09:45:05 +00:00
it - > second . first - > setMarkColor ( markColor ) ;
it - > second . second - > setMarkColor ( markColor ) ;
}
2018-04-07 08:44:39 +00:00
void SkeletonGraphicsWidget : : nodeOriginChanged ( QUuid nodeId )
{
2018-11-03 08:09:42 +00:00
const SkeletonNode * 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 ;
}
QPointF mainPos = scenePosFromUnified ( QPointF ( node - > x , node - > y ) ) ;
QPointF sidePos = scenePosFromUnified ( QPointF ( node - > z , node - > y ) ) ;
it - > second . first - > setOrigin ( mainPos ) ;
it - > second . second - > setOrigin ( sidePos ) ;
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 ;
}
edgeItemIt - > second . first - > updateAppearance ( ) ;
edgeItemIt - > second . second - > updateAppearance ( ) ;
}
}
void SkeletonGraphicsWidget : : edgeChanged ( QUuid edgeId )
{
}
2018-04-08 01:30:55 +00:00
void SkeletonGraphicsWidget : : partVisibleStateChanged ( QUuid partId )
{
2018-11-03 08:09:42 +00:00
const SkeletonPart * part = m_document - > findPart ( partId ) ;
2018-04-08 01:30:55 +00:00
for ( const auto & nodeId : part - > nodeIds ) {
2018-11-03 08:09:42 +00:00
const SkeletonNode * 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
}
}
2018-04-08 15:08:23 +00:00
bool SkeletonGraphicsWidget : : checkSkeletonItem ( QGraphicsItem * item , bool checked )
{
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 " ) {
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 " ) {
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 ;
}
2018-04-18 01:49:23 +00:00
QUuid SkeletonGraphicsWidget : : querySkeletonItemPartId ( QGraphicsItem * item )
{
if ( item - > data ( 0 ) = = " node " ) {
SkeletonGraphicsNodeItem * nodeItem = ( SkeletonGraphicsNodeItem * ) item ;
2018-11-03 08:09:42 +00:00
const SkeletonNode * node = m_document - > findNode ( nodeItem - > id ( ) ) ;
2018-04-18 01:49:23 +00:00
if ( ! node ) {
qDebug ( ) < < " Find node id failed: " < < nodeItem - > id ( ) ;
return QUuid ( ) ;
}
return node - > partId ;
} else if ( item - > data ( 0 ) = = " edge " ) {
SkeletonGraphicsEdgeItem * edgeItem = ( SkeletonGraphicsEdgeItem * ) item ;
2018-11-03 08:09:42 +00:00
const SkeletonEdge * edge = m_document - > findEdge ( edgeItem - > id ( ) ) ;
2018-04-18 01:49:23 +00:00
if ( ! edge ) {
qDebug ( ) < < " Find edge id failed: " < < edgeItem - > id ( ) ;
return QUuid ( ) ;
}
return edge - > partId ;
}
return QUuid ( ) ;
}
2018-04-08 15:08:23 +00:00
SkeletonProfile SkeletonGraphicsWidget : : readSkeletonItemProfile ( QGraphicsItem * item )
{
if ( item - > data ( 0 ) = = " node " ) {
SkeletonGraphicsNodeItem * nodeItem = ( SkeletonGraphicsNodeItem * ) item ;
return nodeItem - > profile ( ) ;
} else if ( item - > data ( 0 ) = = " edge " ) {
SkeletonGraphicsEdgeItem * edgeItem = ( SkeletonGraphicsEdgeItem * ) item ;
return edgeItem - > profile ( ) ;
}
return SkeletonProfile : : Unknown ;
}
void SkeletonGraphicsWidget : : checkRangeSelection ( )
{
std : : set < QGraphicsItem * > newSet ;
std : : set < QGraphicsItem * > deleteSet ;
2018-04-12 13:24:51 +00:00
std : : set < QGraphicsItem * > forceDeleteSet ;
2018-04-08 15:08:23 +00:00
SkeletonProfile choosenProfile = SkeletonProfile : : Unknown ;
if ( ! m_rangeSelectionSet . empty ( ) ) {
auto it = m_rangeSelectionSet . begin ( ) ;
choosenProfile = readSkeletonItemProfile ( * it ) ;
}
if ( m_selectionItem - > isVisible ( ) ) {
QList < QGraphicsItem * > items = scene ( ) - > items ( m_selectionItem - > sceneBoundingRect ( ) ) ;
for ( auto it = items . begin ( ) ; it ! = items . end ( ) ; it + + ) {
QGraphicsItem * item = * it ;
2018-04-12 13:24:51 +00:00
if ( QGuiApplication : : queryKeyboardModifiers ( ) . testFlag ( Qt : : AltModifier ) ) {
checkSkeletonItem ( item , false ) ;
forceDeleteSet . insert ( item ) ;
} else {
if ( SkeletonProfile : : Unknown = = choosenProfile ) {
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 ) ) {
for ( const auto & item : m_rangeSelectionSet ) {
if ( newSet . find ( item ) = = newSet . end ( ) ) {
checkSkeletonItem ( item , false ) ;
deleteSet . insert ( item ) ;
}
}
}
for ( const auto & item : newSet ) {
m_rangeSelectionSet . insert ( item ) ;
}
for ( const auto & item : deleteSet ) {
m_rangeSelectionSet . erase ( item ) ;
}
2018-04-12 13:24:51 +00:00
for ( const auto & item : forceDeleteSet ) {
m_rangeSelectionSet . erase ( item ) ;
}
2018-04-08 15:08:23 +00:00
}
void SkeletonGraphicsWidget : : clearRangeSelection ( )
{
for ( const auto & item : m_rangeSelectionSet ) {
checkSkeletonItem ( item , false ) ;
}
m_rangeSelectionSet . clear ( ) ;
}
void SkeletonGraphicsWidget : : readMergedSkeletonNodeSetFromRangeSelection ( std : : set < SkeletonGraphicsNodeItem * > * nodeItemSet )
{
for ( const auto & it : m_rangeSelectionSet ) {
QGraphicsItem * item = it ;
if ( item - > data ( 0 ) = = " node " ) {
nodeItemSet - > insert ( ( SkeletonGraphicsNodeItem * ) item ) ;
} else if ( item - > data ( 0 ) = = " edge " ) {
SkeletonGraphicsEdgeItem * edgeItem = ( SkeletonGraphicsEdgeItem * ) item ;
if ( edgeItem - > firstItem ( ) & & edgeItem - > secondItem ( ) ) {
nodeItemSet - > insert ( edgeItem - > firstItem ( ) ) ;
nodeItemSet - > insert ( edgeItem - > secondItem ( ) ) ;
}
}
}
}
void SkeletonGraphicsWidget : : readSkeletonNodeAndEdgeIdSetFromRangeSelection ( std : : set < QUuid > * nodeIdSet , std : : set < QUuid > * edgeIdSet )
{
for ( const auto & it : m_rangeSelectionSet ) {
QGraphicsItem * item = it ;
if ( item - > data ( 0 ) = = " node " ) {
nodeIdSet - > insert ( ( ( SkeletonGraphicsNodeItem * ) item ) - > id ( ) ) ;
} else if ( item - > data ( 0 ) = = " edge " ) {
2018-06-21 08:24:18 +00:00
if ( nullptr ! = edgeIdSet )
edgeIdSet - > insert ( ( ( SkeletonGraphicsEdgeItem * ) item ) - > id ( ) ) ;
2018-04-08 15:08:23 +00:00
}
}
}
2018-04-09 11:13:34 +00:00
bool SkeletonGraphicsWidget : : readSkeletonNodeAndAnyEdgeOfNodeFromRangeSelection ( SkeletonGraphicsNodeItem * * nodeItem , SkeletonGraphicsEdgeItem * * edgeItem )
{
SkeletonGraphicsNodeItem * choosenNodeItem = nullptr ;
SkeletonGraphicsEdgeItem * choosenEdgeItem = nullptr ;
for ( const auto & it : m_rangeSelectionSet ) {
QGraphicsItem * item = it ;
if ( item - > data ( 0 ) = = " node " ) {
choosenNodeItem = ( SkeletonGraphicsNodeItem * ) item ;
} else if ( item - > data ( 0 ) = = " edge " ) {
choosenEdgeItem = ( SkeletonGraphicsEdgeItem * ) item ;
}
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 ;
}
2018-04-18 01:49:23 +00:00
void SkeletonGraphicsWidget : : selectPartAllById ( QUuid partId )
{
unselectAll ( ) ;
for ( const auto & it : nodeItemMap ) {
SkeletonGraphicsNodeItem * item = it . second . first ;
2018-11-03 08:09:42 +00:00
const SkeletonNode * node = m_document - > findNode ( item - > id ( ) ) ;
2018-04-18 01:49:23 +00:00
if ( ! node )
continue ;
if ( node - > partId ! = partId )
continue ;
addItemToRangeSelection ( item ) ;
}
for ( const auto & it : edgeItemMap ) {
SkeletonGraphicsEdgeItem * item = it . second . first ;
2018-11-03 08:09:42 +00:00
const SkeletonEdge * edge = m_document - > findEdge ( item - > id ( ) ) ;
2018-04-18 01:49:23 +00:00
if ( ! edge )
continue ;
if ( edge - > partId ! = partId )
continue ;
addItemToRangeSelection ( item ) ;
}
hoverPart ( QUuid ( ) ) ;
}
2018-05-12 10:07:46 +00:00
void SkeletonGraphicsWidget : : addSelectNode ( QUuid nodeId )
{
const auto & findResult = nodeItemMap . find ( nodeId ) ;
if ( findResult = = nodeItemMap . end ( ) ) {
qDebug ( ) < < " addSelectNode failed because of node id not exists:<< " < < nodeId ;
return ;
}
addItemToRangeSelection ( findResult - > second . first ) ;
hoverPart ( QUuid ( ) ) ;
}
void SkeletonGraphicsWidget : : addSelectEdge ( QUuid edgeId )
{
const auto & findResult = edgeItemMap . find ( edgeId ) ;
if ( findResult = = edgeItemMap . end ( ) ) {
qDebug ( ) < < " addSelectEdge failed because of edge id not exists:<< " < < edgeId ;
return ;
}
addItemToRangeSelection ( findResult - > second . first ) ;
hoverPart ( QUuid ( ) ) ;
}
2018-09-01 02:17:26 +00:00
void SkeletonGraphicsWidget : : addPartToSelection ( QUuid partId )
{
SkeletonProfile choosenProfile = SkeletonProfile : : Main ;
if ( m_hoveredNodeItem ) {
choosenProfile = m_hoveredNodeItem - > profile ( ) ;
} else if ( m_hoveredEdgeItem ) {
choosenProfile = m_hoveredEdgeItem - > profile ( ) ;
}
QUuid choosenPartId = partId ;
for ( const auto & it : nodeItemMap ) {
SkeletonGraphicsNodeItem * item = SkeletonProfile : : Main = = choosenProfile ? it . second . first : it . second . second ;
2018-11-03 08:09:42 +00:00
const SkeletonNode * 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 ) ;
}
for ( const auto & it : edgeItemMap ) {
SkeletonGraphicsEdgeItem * item = SkeletonProfile : : Main = = choosenProfile ? it . second . first : it . second . second ;
2018-11-03 08:09:42 +00:00
const SkeletonEdge * 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 ( ) ;
SkeletonProfile choosenProfile = SkeletonProfile : : Main ;
QUuid startNodeId ;
if ( m_hoveredNodeItem ) {
choosenProfile = m_hoveredNodeItem - > profile ( ) ;
const SkeletonNode * node = m_document - > findNode ( m_hoveredNodeItem - > id ( ) ) ;
if ( node )
startNodeId = node - > id ;
} else if ( m_hoveredEdgeItem ) {
choosenProfile = m_hoveredEdgeItem - > profile ( ) ;
const SkeletonEdge * edge = m_document - > findEdge ( m_hoveredEdgeItem - > id ( ) ) ;
if ( edge & & ! edge - > nodeIds . empty ( ) )
startNodeId = * edge - > nodeIds . begin ( ) ;
}
if ( startNodeId . isNull ( ) )
return ;
std : : set < QUuid > visitedNodes ;
std : : set < QUuid > visitedEdges ;
std : : queue < QUuid > nodeIds ;
nodeIds . push ( startNodeId ) ;
while ( ! nodeIds . empty ( ) ) {
QUuid nodeId = nodeIds . front ( ) ;
nodeIds . pop ( ) ;
if ( visitedNodes . find ( nodeId ) ! = visitedNodes . end ( ) )
continue ;
const SkeletonNode * node = m_document - > findNode ( nodeId ) ;
if ( nullptr = = node )
continue ;
visitedNodes . insert ( nodeId ) ;
for ( const auto & edgeId : node - > edgeIds ) {
const SkeletonEdge * edge = m_document - > findEdge ( edgeId ) ;
if ( nullptr = = edge )
continue ;
visitedEdges . insert ( edgeId ) ;
for ( const auto & nodeIdOfEdge : edge - > nodeIds ) {
if ( visitedNodes . find ( nodeIdOfEdge ) ! = visitedNodes . end ( ) )
continue ;
nodeIds . push ( nodeIdOfEdge ) ;
}
}
}
for ( const auto & it : nodeItemMap ) {
SkeletonGraphicsNodeItem * item = SkeletonProfile : : Main = = choosenProfile ? it . second . first : it . second . second ;
if ( visitedNodes . find ( item - > id ( ) ) = = visitedNodes . end ( ) )
continue ;
addItemToRangeSelection ( item ) ;
}
for ( const auto & it : edgeItemMap ) {
SkeletonGraphicsEdgeItem * item = SkeletonProfile : : Main = = choosenProfile ? it . second . first : it . second . second ;
if ( visitedEdges . find ( item - > id ( ) ) = = visitedEdges . end ( ) )
continue ;
addItemToRangeSelection ( item ) ;
}
}
2018-04-09 05:22:25 +00:00
void SkeletonGraphicsWidget : : selectPartAll ( )
{
unselectAll ( ) ;
SkeletonProfile choosenProfile = SkeletonProfile : : Main ;
QUuid choosenPartId ;
if ( m_hoveredNodeItem ) {
choosenProfile = m_hoveredNodeItem - > profile ( ) ;
2018-11-03 08:09:42 +00:00
const SkeletonNode * 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 ( ) ;
2018-11-03 08:09:42 +00:00
const SkeletonEdge * edge = m_document - > findEdge ( m_hoveredEdgeItem - > id ( ) ) ;
2018-04-09 05:22:25 +00:00
if ( edge )
choosenPartId = edge - > partId ;
}
for ( const auto & it : nodeItemMap ) {
SkeletonGraphicsNodeItem * item = SkeletonProfile : : Main = = choosenProfile ? it . second . first : it . second . second ;
2018-11-03 08:09:42 +00:00
const SkeletonNode * 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
}
for ( const auto & it : edgeItemMap ) {
SkeletonGraphicsEdgeItem * item = SkeletonProfile : : Main = = choosenProfile ? it . second . first : it . second . second ;
2018-11-03 08:09:42 +00:00
const SkeletonEdge * 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
}
}
2018-04-09 03:39:04 +00:00
void SkeletonGraphicsWidget : : selectAll ( )
{
unselectAll ( ) ;
SkeletonProfile choosenProfile = SkeletonProfile : : Main ;
if ( m_hoveredNodeItem ) {
choosenProfile = m_hoveredNodeItem - > profile ( ) ;
} else if ( m_hoveredEdgeItem ) {
choosenProfile = m_hoveredEdgeItem - > profile ( ) ;
}
for ( const auto & it : nodeItemMap ) {
SkeletonGraphicsNodeItem * item = SkeletonProfile : : 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
}
for ( const auto & it : edgeItemMap ) {
SkeletonGraphicsEdgeItem * item = SkeletonProfile : : 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
}
}
2018-04-10 08:44:02 +00:00
void SkeletonGraphicsWidget : : addItemToRangeSelection ( QGraphicsItem * item )
{
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
}
void SkeletonGraphicsWidget : : removeItemFromRangeSelection ( QGraphicsItem * item )
{
checkSkeletonItem ( item , false ) ;
m_rangeSelectionSet . erase ( item ) ;
}
2018-04-09 03:39:04 +00:00
void SkeletonGraphicsWidget : : unselectAll ( )
{
for ( const auto & item : m_rangeSelectionSet ) {
checkSkeletonItem ( item , false ) ;
}
m_rangeSelectionSet . clear ( ) ;
}
2018-04-09 08:46:06 +00:00
void SkeletonGraphicsWidget : : cut ( )
{
copy ( ) ;
deleteSelected ( ) ;
}
void SkeletonGraphicsWidget : : copy ( )
{
std : : set < QUuid > nodeIdSet ;
std : : set < QUuid > edgeIdSet ;
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 ( ) ;
2018-08-27 08:50:40 +00:00
std : : vector < QGraphicsItem * > contentItems ;
2018-04-10 07:59:20 +00:00
for ( const auto & it : items ( ) ) {
QGraphicsItem * item = it ;
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 + + ) {
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 ;
const auto & it = m_rangeSelectionSet . begin ( ) ;
QGraphicsItem * item = * it ;
return item - > data ( 0 ) = = " node " ;
}
2018-04-09 14:24:30 +00:00
2018-04-18 01:49:23 +00:00
void SkeletonGraphicsWidget : : hoverPart ( QUuid partId )
{
if ( partId . isNull ( ) ) {
if ( ! m_rangeSelectionSet . empty ( ) ) {
const auto & it = m_rangeSelectionSet . begin ( ) ;
partId = querySkeletonItemPartId ( * it ) ;
}
}
if ( m_lastCheckedPart = = partId )
return ;
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 ;
for ( const auto & item : copiedSet ) {
if ( item - > data ( 0 ) = = " node " ) {
SkeletonGraphicsNodeItem * nodeItem = ( SkeletonGraphicsNodeItem * ) item ;
const auto & find = nodeItemMap . find ( nodeItem - > id ( ) ) ;
if ( find = = nodeItemMap . end ( ) ) {
qDebug ( ) < < " Node item map key not found: " < < nodeItem - > id ( ) ;
return ;
}
checkSkeletonItem ( nodeItem , false ) ;
m_rangeSelectionSet . erase ( nodeItem ) ;
SkeletonGraphicsNodeItem * altNodeItem = nodeItem = = find - > second . first ? find - > second . second : find - > second . first ;
if ( checkSkeletonItem ( altNodeItem , true ) )
m_rangeSelectionSet . insert ( altNodeItem ) ;
} else if ( item - > data ( 0 ) = = " edge " ) {
SkeletonGraphicsEdgeItem * edgeItem = ( SkeletonGraphicsEdgeItem * ) item ;
const auto & find = edgeItemMap . find ( edgeItem - > id ( ) ) ;
if ( find = = edgeItemMap . end ( ) ) {
qDebug ( ) < < " Edge item map key not found: " < < edgeItem - > id ( ) ;
return ;
}
checkSkeletonItem ( edgeItem , false ) ;
m_rangeSelectionSet . erase ( edgeItem ) ;
SkeletonGraphicsEdgeItem * altEdgeItem = edgeItem = = find - > second . first ? find - > second . second : find - > second . first ;
if ( checkSkeletonItem ( altEdgeItem , true ) )
m_rangeSelectionSet . insert ( altEdgeItem ) ;
}
}
}
2018-04-21 00:23:27 +00:00
void SkeletonGraphicsWidget : : setItemHoveredOnAllProfiles ( QGraphicsItem * item , bool hovered )
{
if ( item - > data ( 0 ) = = " node " ) {
SkeletonGraphicsNodeItem * nodeItem = ( SkeletonGraphicsNodeItem * ) item ;
const auto & find = nodeItemMap . find ( nodeItem - > id ( ) ) ;
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 " ) {
SkeletonGraphicsEdgeItem * edgeItem = ( SkeletonGraphicsEdgeItem * ) item ;
const auto & find = edgeItemMap . find ( edgeItem - > id ( ) ) ;
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 ( ) ;
if ( movedUpdateVersion = = m_ikMoveUpdateVersion & &
! m_ikMoveEndEffectorId . isNull ( ) ) {
emit batchChangeBegin ( ) ;
for ( const auto & it : m_ikMover - > ikNodes ( ) ) {
emit setNodeOrigin ( it . id , it . newPosition . x ( ) , it . newPosition . y ( ) , it . newPosition . z ( ) ) ;
}
emit batchChangeEnd ( ) ;
emit groupOperationAdded ( ) ;
}
delete m_ikMover ;
m_ikMover = nullptr ;
if ( movedUpdateVersion ! = m_ikMoveUpdateVersion & &
! m_ikMoveEndEffectorId . isNull ( ) ) {
ikMove ( m_ikMoveEndEffectorId , m_ikMoveTarget ) ;
}
}
2018-04-21 00:23:27 +00:00
2018-05-24 01:44:40 +00:00
void SkeletonGraphicsWidget : : ikMove ( QUuid endEffectorId , QVector3D target )
{
m_ikMoveEndEffectorId = endEffectorId ;
m_ikMoveTarget = target ;
m_ikMoveUpdateVersion + + ;
if ( nullptr ! = m_ikMover ) {
return ;
}
QThread * thread = new QThread ;
m_ikMover = new SkeletonIkMover ( ) ;
m_ikMover - > setUpdateVersion ( m_ikMoveUpdateVersion ) ;
m_ikMover - > setTarget ( m_ikMoveTarget ) ;
QUuid nodeId = endEffectorId ;
std : : set < QUuid > historyNodeIds ;
std : : vector < std : : pair < QUuid , QVector3D > > appendNodes ;
for ( ; ; ) {
historyNodeIds . insert ( nodeId ) ;
const auto node = m_document - > findNode ( nodeId ) ;
if ( nullptr = = node )
break ;
appendNodes . push_back ( std : : make_pair ( nodeId , QVector3D ( node - > x , node - > y , node - > z ) ) ) ;
if ( node - > edgeIds . size ( ) < 1 | | node - > edgeIds . size ( ) > 2 )
break ;
QUuid choosenNodeId ;
for ( const auto & edgeId : node - > edgeIds ) {
const auto edge = m_document - > findEdge ( edgeId ) ;
if ( nullptr = = edge )
break ;
QUuid neighborNodeId = edge - > neighborOf ( nodeId ) ;
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 ( ) ;
}
2018-05-30 01:51:38 +00:00
2018-10-25 00:19:38 +00:00
void SkeletonGraphicsWidget : : setSelectedNodesBoneMark ( BoneMark boneMark )
2018-09-14 09:45:05 +00:00
{
std : : set < QUuid > nodeIdSet ;
std : : set < QUuid > edgeIdSet ;
readSkeletonNodeAndEdgeIdSetFromRangeSelection ( & nodeIdSet , & edgeIdSet ) ;
if ( ! nodeIdSet . empty ( ) ) {
emit batchChangeBegin ( ) ;
for ( const auto & id : nodeIdSet ) {
emit setNodeBoneMark ( id , boneMark ) ;
}
emit batchChangeEnd ( ) ;
emit groupOperationAdded ( ) ;
}
}
2018-11-05 15:47:21 +00:00
void SkeletonGraphicsWidget : : setNodePositionModifyOnly ( bool nodePositionModifyOnly )
{
m_nodePositionModifyOnly = nodePositionModifyOnly ;
}