/* ************************************************************************** description -------------------- copyright : (C) 2000-2001 by Andreas Zehender email : zehender@kde.org ************************************************************************** ************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * **************************************************************************/ #include "pmsorcontrolpoint.h" #include "pmmath.h" #include PMSorControlPoint::PMSorControlPoint( PMSorControlPoint* prev, const PMVector& point, PMSorControlPoint::CPType type, int id, const TQString& description ) : PMControlPoint( id, description ) { m_point = point; m_type = type; m_pPrev = prev; if( m_pPrev ) m_pPrev->m_pNext = this; m_pNext = 0; m_pSorLink = 0; } void PMSorControlPoint::graphicalChangeStarted( ) { if( m_pPrev && !m_pPrev->m_pPrev && !m_pPrev->selected( ) ) m_pPrev->graphicalChangeStarted( ); if( m_pNext && !m_pNext->m_pNext && !m_pNext->selected( ) ) m_pNext->graphicalChangeStarted( ); m_original2DPoint = m_point; m_originalPoint = to3D( m_point ); } void PMSorControlPoint::graphicalChange( const PMVector& startPoint, const PMVector& /*viewNormal*/, const PMVector& endPoint ) { if( !m_pPrev && m_pNext->selected( ) || !m_pNext && m_pPrev->selected( ) ) return; m_point = to2D( m_originalPoint + endPoint - startPoint ); if( m_pSorLink && m_pSorLink->selected( ) ) { PMSorControlPoint* ll = m_pSorLink; PMVector op = ll->to2D( ll->m_originalPoint + endPoint - startPoint ); if( ( m_point - m_original2DPoint ).abs( ) < ( op - ll->m_original2DPoint ).abs( ) ) m_point = op; } if( m_pPrev && m_pNext ) { if( m_pPrev->m_pPrev ) if( ( m_point[1] - m_pPrev->m_point[1] ) < c_sorTolerance ) m_point[1] = m_pPrev->m_point[1] + c_sorTolerance; if( m_pNext->m_pNext ) if( ( m_pNext->m_point[1] - m_point[1] ) < c_sorTolerance ) m_point[1] = m_pNext->m_point[1] - c_sorTolerance; } if( m_point[0] < 0.0 ) m_point[0] = 0.0; if( m_pPrev && !m_pPrev->m_pPrev ) { m_pPrev->m_point = m_point + m_pPrev->m_original2DPoint - m_original2DPoint; m_pPrev->setChanged( ); } if( m_pNext && !m_pNext->m_pNext ) { m_pNext->m_point = m_point + m_pNext->m_original2DPoint - m_original2DPoint; m_pNext->setChanged( ); } } void PMSorControlPoint::snapToGrid( ) { int i; double d = moveGrid( ); bool diff = false; PMVector change( 2 ); PMSorControlPoint* basePoint = 0; PMSorControlPoint* linkedPoint = 0; if( !m_pPrev ) basePoint = m_pNext; if( !m_pNext ) basePoint = m_pPrev; if( m_pPrev && !m_pPrev->m_pPrev ) linkedPoint = m_pPrev; if( m_pNext && !m_pNext->m_pNext ) linkedPoint = m_pNext; if( basePoint && basePoint->selected( ) ) { m_point -= basePoint->m_point; diff = true; } if( !approxZero( d ) ) { for( i = 0; i < 2; i++ ) { change[i] = -m_point[i]; m_point[i] = rint( m_point[i] / d ) * d; change[i] += m_point[i]; } } if( diff ) m_point += basePoint->m_point; if( linkedPoint ) { linkedPoint->m_point += change; linkedPoint->setChanged( ); } setChanged( ); } PMVector PMSorControlPoint::to2D( const PMVector& v ) const { PMVector result( 2 ); switch( m_type ) { case PM2DXY: result[0] = v[0]; result[1] = v[1]; break; case PM2DXZ: result[0] = v[0]; result[1] = v[2]; break; case PM2DYZ: result[0] = v[1]; result[1] = v[2]; break; case PM2DYX: result[0] = v[1]; result[1] = v[0]; break; case PM2DZX: result[0] = v[2]; result[1] = v[0]; break; case PM2DZY: result[0] = v[2]; result[1] = v[1]; break; } return result; } PMVector PMSorControlPoint::to3D( const PMVector& vec ) const { PMVector result( 3 ); switch( m_type ) { case PM2DXY: result[0] = vec[0]; result[1] = vec[1]; result[2] = 0.0; break; case PM2DXZ: result[0] = vec[0]; result[1] = 0.0; result[2] = vec[1]; break; case PM2DYZ: result[0] = 0.0; result[1] = vec[0]; result[2] = vec[1]; break; case PM2DYX: result[1] = vec[0]; result[0] = vec[1]; result[2] = 0.0; break; case PM2DZX: result[2] = vec[0]; result[0] = vec[1]; result[1] = 0.0; break; case PM2DZY: result[2] = vec[0]; result[1] = vec[1]; result[0] = 0.0; break; } return result; } bool PMSorControlPoint::hasExtraLine( ) const { return( !m_pPrev || !m_pNext ); } PMVector PMSorControlPoint::extraLineStart( ) const { return position( ); } PMVector PMSorControlPoint::extraLineEnd( ) const { if( !m_pPrev && m_pNext ) return m_pNext->position( ); if( m_pPrev && !m_pNext ) return m_pPrev->position( ); return PMVector( 0, 0, 0 ); }