/*************************************************************************** pmtorus.cpp - description ------------------- copyright : (C) 2001 Philippe Van Hecke email : lephiloux@tiscalinet.be copyright : (C) 2002 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 "pmtorus.h" #include "pmxmlhelper.h" #include "pmtorusedit.h" #include "pmmemento.h" #include "pmviewstructure.h" #include "pm3dcontrolpoint.h" #include "pmdistancecontrolpoint.h" #include "pmdefaults.h" #include <klocale.h> /** default param for the Torus */ const double c_defaultminorRadius = 0.25; const double c_defaultmajorRadius = 0.5; const bool c_defaultsturm = false; /** default Torus structure */ PMViewStructure* PMTorus::s_pDefaultViewStructure = 0; int PMTorus::s_vStep = c_defaultTorusVSteps; int PMTorus::s_uStep = c_defaultTorusUSteps; int PMTorus::s_parameterKey = 0; PMDefinePropertyClass( PMTorus, PMTorusProperty ); PMMetaObject* PMTorus::s_pMetaObject = 0; PMObject* createNewTorus( PMPart* part ) { return new PMTorus( part ); } PMTorus::PMTorus( PMPart* part ) : Base( part ) { m_minorRadius = c_defaultminorRadius; m_majorRadius = c_defaultmajorRadius; m_sturm = c_defaultsturm ; } PMTorus::PMTorus( const PMTorus& t ) : Base( t ) { m_minorRadius = t.m_minorRadius; m_majorRadius = t.m_majorRadius; m_sturm = t.m_sturm; } PMTorus::~PMTorus( ) { } TQString PMTorus::description( ) const { return i18n( "torus" ); } PMMetaObject* PMTorus::metaObject( ) const { if( !s_pMetaObject ) { s_pMetaObject = new PMMetaObject( "Torus", Base::metaObject( ), createNewTorus ); s_pMetaObject->addProperty( new PMTorusProperty( "minorRadius", &PMTorus::setMinorRadius, &PMTorus::minorRadius ) ); s_pMetaObject->addProperty( new PMTorusProperty( "majorRadius", &PMTorus::setMajorRadius, &PMTorus::majorRadius ) ); s_pMetaObject->addProperty( new PMTorusProperty( "sturm", &PMTorus::setSturm, &PMTorus::sturm ) ); } return s_pMetaObject; } void PMTorus::serialize( TQDomElement& e, TQDomDocument& doc ) const { e.setAttribute( "minor_radius", m_minorRadius ); e.setAttribute( "major_radius", m_majorRadius ); e.setAttribute( "sturm", m_sturm ); Base::serialize( e, doc ); } void PMTorus::readAttributes( const PMXMLHelper& h ) { m_minorRadius = h.doubleAttribute( "minor_radius", c_defaultminorRadius ); m_majorRadius = h.doubleAttribute( "major_radius", c_defaultmajorRadius ); m_sturm = h.boolAttribute( "sturm", c_defaultsturm ); Base::readAttributes( h ); } PMDialogEditBase* PMTorus::editWidget( TQWidget* parent ) const { return new PMTorusEdit( parent ); } void PMTorus::restoreMemento( PMMemento* s ) { PMMementoDataIterator it( s ); PMMementoData* data; for( ; it.current( ); ++it ) { data = it.current( ); if( data->objectType( ) == s_pMetaObject ) { switch( data->valueID( ) ) { case PMMinorRadiusID: setMinorRadius( data->doubleData( ) ); break; case PMMajorRadiusID: setMajorRadius( data->doubleData( ) ); break; case PMSturmID: setSturm( data->boolData( ) ); default: kdError( PMArea ) << "Wrong ID in PMTorus::restoreMemento\n"; break; } } } Base::restoreMemento( s ); } void PMTorus::controlPoints( PMControlPointList& list ) { PMVector majorCenter( 0, 0, 0 ); /** control points of the major radius */ list.append( new PMDistanceControlPoint( majorCenter, PMVector( 1.0, 0.0, 0.0 ), m_majorRadius, PMMajorRadiusID, i18n( "Major radius (x)" ) ) ); PMDistanceControlPoint* rcp = new PMDistanceControlPoint( majorCenter, PMVector( 0.0, 0.0, 1.0 ), m_majorRadius, PMMajorRadiusID, i18n( "Major radius (z)" ) ); list.append( rcp ); PMVector minorCenter( 0.0, 0.0, m_majorRadius ); list.append( new PMDistanceControlPoint( rcp, PMVector( 0.0, 1.0, 0.0 ), m_minorRadius, PMMinorRadiusID, i18n( "Minor radius (y)" ) ) ); list.append( new PMDistanceControlPoint( rcp, PMVector( 0.0, 0.0, 1.0 ), m_minorRadius, PMMinorRadiusID, i18n( "Minor radius (z)" ) ) ); } void PMTorus::controlPointsChanged( PMControlPointList& list ) { bool majorChanged = false, minorChanged = false; PMControlPoint* p; for( p = list.first( ); p; p = list.next( ) ) { if( p->changed( ) ) { switch( p->id( ) ) { case PMMinorRadiusID: setMinorRadius( ( ( PMDistanceControlPoint* ) p )->distance( ) ); ( ( PMDistanceControlPoint* ) p )->setDistance( m_minorRadius ); minorChanged = true; break; case PMMajorRadiusID: setMajorRadius( ( ( PMDistanceControlPoint* ) p )->distance( ) ); ( ( PMDistanceControlPoint* ) p )->setDistance( m_majorRadius ); majorChanged = true; break; default: kdError( PMArea ) << "Wrong ID in PMTorus::controlPointsChanged\n"; break; } } } if( majorChanged ) for( p = list.first( ); p; p = list.next( ) ) if( p->id( ) == PMMajorRadiusID ) ( ( PMDistanceControlPoint* ) p )->setDistance( m_majorRadius ); if( minorChanged ) for( p = list.first( ); p; p = list.next( ) ) if( p->id( ) == PMMinorRadiusID ) ( ( PMDistanceControlPoint* ) p )->setDistance( m_minorRadius ); } bool PMTorus::isDefault( ) { if( ( m_minorRadius == c_defaultminorRadius ) && ( m_majorRadius == c_defaultmajorRadius ) && globalDetail( ) ) return true; return false; } void PMTorus::createViewStructure( ) { if( !m_pViewStructure ) { m_pViewStructure = new PMViewStructure( defaultViewStructure( ) ); m_pViewStructure->points( ).detach( ); } int uStep = (int)( ( (float)s_uStep / 2 ) * ( displayDetail( ) + 1 ) ); int vStep = (int)( ( (float)s_vStep / 2 ) * ( displayDetail( ) + 1 ) ); unsigned ptsSize = vStep * uStep; unsigned lineSize = vStep * uStep * 2; if( ptsSize != m_pViewStructure->points( ).size( ) ) m_pViewStructure->points( ).resize( ptsSize ); createPoints( m_pViewStructure->points( ), m_minorRadius, m_majorRadius, uStep, vStep ); if( lineSize != m_pViewStructure->lines( ).size( ) ) { m_pViewStructure->lines( ).detach( ); m_pViewStructure->lines( ).resize( lineSize ); createLines( m_pViewStructure->lines( ), uStep, vStep ); } } PMViewStructure* PMTorus::defaultViewStructure( ) const { if( !s_pDefaultViewStructure || s_pDefaultViewStructure->parameterKey( ) != viewStructureParameterKey( ) ) { delete s_pDefaultViewStructure; s_pDefaultViewStructure = 0; int uStep = (int)( ( (float)s_uStep / 2 ) * ( globalDetailLevel( ) + 1 ) ); int vStep = (int)( ( (float)s_vStep / 2 ) * ( globalDetailLevel( ) + 1 ) ); s_pDefaultViewStructure = new PMViewStructure( vStep * uStep , vStep * uStep * 2 ); createPoints( s_pDefaultViewStructure->points( ), c_defaultminorRadius, c_defaultmajorRadius, uStep, vStep ); createLines( s_pDefaultViewStructure->lines( ), uStep, vStep ); } return s_pDefaultViewStructure; } void PMTorus::createLines( PMLineArray& lines, int uStep, int vStep ) { int u, v; for( u = 0; u < uStep; ++u ) { for( v = 0; v < vStep; ++v ) { lines[ u * vStep + v ] = PMLine( u * vStep + v, u * vStep + ( (v+1) % vStep ) ); lines[ uStep * vStep + u * vStep + v ] = PMLine( u * vStep + v, ( (u+1) % uStep ) * vStep + v ); } } } void PMTorus::createPoints( PMPointArray& points, double minor_radius, double major_radius, int uStep, int vStep ) { double l_UradStep = ( 2.0 * M_PI ) / uStep; double l_VradStep = ( 2.0 * M_PI ) / vStep; double l_u = l_UradStep; int u, v; for( u = 0; u < uStep; ++u ) { double l_v = 0.0; double y = minor_radius * sin ( l_u ); double l_rcosu = major_radius + minor_radius * cos( l_u ); for( v = 0; v < vStep; ++v ) { double x = l_rcosu * cos( l_v ); double z = l_rcosu * sin( l_v ); points[u * vStep + v ] = PMPoint( x, y, z ); l_v = l_v + l_VradStep; } l_u = l_u + l_UradStep; } } void PMTorus::setMinorRadius( double minor_radius ) { if( m_minorRadius != minor_radius ) { if( m_pMemento ) m_pMemento->addData( s_pMetaObject, PMMinorRadiusID, m_minorRadius ); m_minorRadius = minor_radius; setViewStructureChanged( ); } } void PMTorus::setMajorRadius( double major_radius ) { if( m_majorRadius != major_radius ) { if( m_pMemento ) m_pMemento->addData( s_pMetaObject, PMMajorRadiusID, m_majorRadius ); m_majorRadius = major_radius; setViewStructureChanged( ); } } void PMTorus::setSturm( bool sturm ) { if( m_sturm != sturm ) { if( m_pMemento ) m_pMemento->addData( s_pMetaObject, PMSturmID, m_sturm ); m_sturm = sturm; setViewStructureChanged( ); } } void PMTorus::setUSteps( int u ) { if( u >= 2 ) { s_uStep = u; if( s_pDefaultViewStructure ) { delete s_pDefaultViewStructure; s_pDefaultViewStructure = 0; } } else kdDebug( PMArea ) << "PMTorus::setUSteps: U must be greater than 1\n"; s_parameterKey++; } void PMTorus::setVSteps( int v ) { if( v >= 4 ) { s_vStep = v; if( s_pDefaultViewStructure ) { delete s_pDefaultViewStructure; s_pDefaultViewStructure = 0; } } else kdDebug( PMArea ) << "PMTorus::setVSteps: V must be greater than 3\n"; s_parameterKey++; } void PMTorus::cleanUp( ) const { if( s_pDefaultViewStructure ) delete s_pDefaultViewStructure; s_pDefaultViewStructure = 0; if( s_pMetaObject ) { delete s_pMetaObject; s_pMetaObject = 0; } Base::cleanUp( ); }