summaryrefslogtreecommitdiffstats
path: root/kpovmodeler/pmtorus.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kpovmodeler/pmtorus.cpp')
-rw-r--r--kpovmodeler/pmtorus.cpp379
1 files changed, 379 insertions, 0 deletions
diff --git a/kpovmodeler/pmtorus.cpp b/kpovmodeler/pmtorus.cpp
new file mode 100644
index 00000000..c6f4238a
--- /dev/null
+++ b/kpovmodeler/pmtorus.cpp
@@ -0,0 +1,379 @@
+/***************************************************************************
+ pmtorus.cpp - description
+ -------------------
+ copyright : (C) 2001 Philippe Van Hecke
+ copyright : (C) 2002 Andreas Zehender
+***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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( )
+{
+}
+
+
+QString 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( QDomElement& e, QDomDocument& 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( QWidget* 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( );
+}