You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdegraphics/kpovmodeler/pmpovrayparser.cpp

7214 lines
191 KiB

/*
**************************************************************************
description
--------------------
copyright : (C) 2000-2003 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 "pmpovrayparser.h"
#include <tdelocale.h>
#include <tqvaluelist.h>
#include "pmpart.h"
#include "pmscanner.h"
#include "pmtokens.h"
#include "pmcolor.h"
#include "pmallobjects.h"
#include "pmprototypemanager.h"
#include "pmxmlhelper.h"
PMPovrayParser::PMPovrayParser( PMPart* part, TQIODevice* dev )
: PMParser( part, dev )
{
init( );
}
PMPovrayParser::PMPovrayParser( PMPart* part, const TQByteArray& array )
: PMParser( part, array )
{
init( );
}
PMPovrayParser::~PMPovrayParser( )
{
if( m_pScanner )
delete m_pScanner;
}
void PMPovrayParser::init( )
{
m_pScanner = new PMScanner( m_pDevice );
m_consumedTokens = 0;
m_skippedComments.setAutoDelete( true );
m_bLastPMCommentEmpty = true;
}
void PMPovrayParser::nextToken( )
{
m_token = m_pScanner->nextToken( );
m_consumedTokens++;
setCurrentLine( m_pScanner->currentLine( ) );
if( ( m_token == SCANNER_ERROR_TOK ) || ( m_token == COMMENT_TOK )
|| ( m_token == LINE_COMMENT_TOK ) || ( m_token == PMNAME_TOK ) )
{
// create the objects (string) only if necessary
PMComment* c;
int lastCommentLine = -2;
TQString commentText;
while( ( m_token == SCANNER_ERROR_TOK ) || ( m_token == COMMENT_TOK )
|| ( m_token == LINE_COMMENT_TOK ) || ( m_token == PMNAME_TOK ) )
{
switch( m_token )
{
case SCANNER_ERROR_TOK:
printError( m_pScanner->error( ) );
lastCommentLine = -2;
break;
case LINE_COMMENT_TOK:
commentText = m_pScanner->sValue( );
if( lastCommentLine == ( m_pScanner->currentLine( ) - 1 ) )
{
c = m_skippedComments.last( );
if( c )
c->setText( c->text( ) + '\n' + commentText );
else
{
c = new PMComment( m_pPart, commentText );
m_skippedComments.append( c );
}
}
else
{
c = new PMComment( m_pPart, m_pScanner->sValue( ) );
m_skippedComments.append( c );
}
lastCommentLine = m_pScanner->currentLine( );
break;
case COMMENT_TOK:
c = new PMComment( m_pPart, m_pScanner->sValue( ) );
m_skippedComments.append( c );
lastCommentLine = -2;
break;
case PMNAME_TOK:
// Special comment
m_lastPMComment = m_pScanner->sValue( );
m_bLastPMCommentEmpty = false;
lastCommentLine = -2;
break;
default:
lastCommentLine = -2;
break;
}
m_token = m_pScanner->nextToken( );
m_consumedTokens++;
}
}
}
bool PMPovrayParser::isTrue( ) const
{
if( ( m_token == ON_TOK ) || ( m_token == TRUE_TOK ) || ( m_token == YES_TOK ) )
return true;
return false;
}
bool PMPovrayParser::isFalse( ) const
{
if( ( m_token == OFF_TOK ) || ( m_token == FALSE_TOK ) || ( m_token == NO_TOK ) )
return true;
return false;
}
void PMPovrayParser::topParse( )
{
nextToken( );
do
{
if( !parseChildObjects( 0 ) )
m_token = EOF_TOK;
if( m_token != EOF_TOK )
{
printUnexpected( m_pScanner->sValue( ) );
nextToken( );
}
}
while( m_token != EOF_TOK );
if( errors( ) || warnings( ) )
printMessage( PMMSpecialRawComment );
}
bool PMPovrayParser::parseBool( )
{
if( isFalse( ) )
{
nextToken( );
return false;
}
if( isTrue( ) )
{
nextToken( );
return true;
}
PMValue v;
if( parseNumericExpression( v, true ) )
{
switch( v.type( ) )
{
case PMVFloat:
return v.floatValue( ) > 0.0;
break;
case PMVVector:
return ( v.vector( ) )[0] > 0.0;
break;
default:
printError( i18n( "Boolean expression expected" ) );
break;
}
}
return true;
}
bool PMPovrayParser::parseChildObjects( PMCompositeObject* parent,
int max /* = -1 */ )
{
PMObject* child = 0;
bool finished = false;
bool error = false;
bool noChild = false;
int numParsed = 0;
do
{
if( !m_bLastPMCommentEmpty && parent )
{
if( parent->isA( "NamedObject" ) )
( ( PMNamedObject* ) parent )->setName( m_lastPMComment );
m_bLastPMCommentEmpty = true;
}
if( m_skippedComments.count( ) > 0 )
child = m_skippedComments.take( 0 );
else
{
child = 0;
noChild = false;
// some objects
switch( m_token )
{
case UNION_TOK:
case DIFFERENCE_TOK:
case INTERSECTION_TOK:
case MERGE_TOK:
child = new PMCSG( m_pPart );
error = !parseCSG( ( PMCSG* ) child );
break;
case BOX_TOK:
child = new PMBox( m_pPart );
error = !parseBox( ( PMBox* ) child );
break;
case SPHERE_TOK:
if( ( parent && ( parent->type( ) == "Blob" ) )
|| ( !parent && m_pTopParent
&& ( m_pTopParent->type( ) == "Blob" ) ) )
{
child = new PMBlobSphere( m_pPart );
error = !parseBlobSphere( ( PMBlobSphere* ) child );
}
else
{
child = new PMSphere( m_pPart );
error = !parseSphere( ( PMSphere* ) child );
}
break;
case CYLINDER_TOK:
if( ( parent && ( parent->type( ) == "Blob" ) )
|| ( !parent && m_pTopParent
&& ( m_pTopParent->type( ) == "Blob" ) ) )
{
child = new PMBlobCylinder( m_pPart );
error = !parseBlobCylinder( ( PMBlobCylinder* ) child );
}
else
{
child = new PMCylinder( m_pPart );
error = !parseCylinder( ( PMCylinder* ) child );
}
break;
case CONE_TOK:
child = new PMCone( m_pPart );
error = !parseCone( ( PMCone* ) child );
break;
case TORUS_TOK:
child = new PMTorus( m_pPart );
error = !parseTorus( ( PMTorus* ) child );
break;
case BLOB_TOK:
child = new PMBlob( m_pPart );
error = !parseBlob( ( PMBlob* ) child );
break;
case COMPONENT_TOK:
child = new PMBlobSphere( m_pPart );
error = !parseBlobComponent( ( PMBlobSphere* ) child );
break;
case HEIGHT_FIELD_TOK:
child = new PMHeightField( m_pPart );
error = !parseHeightField( ( PMHeightField* ) child );
break;
case TEXT_TOK:
child = new PMText( m_pPart );
error = !parseText( ( PMText* ) child );
break;
case JULIA_FRACTAL_TOK:
child = new PMJuliaFractal( m_pPart );
error = !parseJuliaFractal( ( PMJuliaFractal* ) child );
break;
case PLANE_TOK:
child = new PMPlane( m_pPart );
error = !parsePlane( ( PMPlane* ) child );
break;
case QUADRIC_TOK:
case CUBIC_TOK:
case QUARTIC_TOK:
case POLY_TOK:
child = new PMPolynom( m_pPart );
error = !parsePolynom( ( PMPolynom* ) child );
break;
case BICUBIC_PATCH_TOK:
child = new PMBicubicPatch( m_pPart );
error = !parseBicubicPatch( ( PMBicubicPatch* ) child );
break;
case DISC_TOK:
child = new PMDisc( m_pPart );
error = !parseDisc( ( PMDisc* ) child );
break;
case TRIANGLE_TOK:
case SMOOTH_TRIANGLE_TOK:
child = new PMTriangle( m_pPart );
error = !parseTriangle( ( PMTriangle* ) child );
break;
case LATHE_TOK:
child = new PMLathe( m_pPart );
error = !parseLathe( ( PMLathe* ) child );
break;
case PRISM_TOK:
child = new PMPrism( m_pPart );
error = !parsePrism( ( PMPrism* ) child );
break;
case SOR_TOK:
child = new PMSurfaceOfRevolution( m_pPart );
error = !parseSor( ( PMSurfaceOfRevolution* ) child );
break;
case SUPERELLIPSOID_TOK:
child = new PMSuperquadricEllipsoid( m_pPart );
error = !parseSqe( ( PMSuperquadricEllipsoid* ) child );
break;
case CAMERA_TOK:
child = new PMCamera( m_pPart );
error = !parseCamera( ( PMCamera* ) child );
break;
case LIGHT_SOURCE_TOK:
child = new PMLight( m_pPart );
error = !parseLight( ( PMLight* ) child );
break;
case LOOKS_LIKE_TOK:
child = new PMLooksLike( m_pPart );
error = !parseLooksLike( ( PMLooksLike* ) child );
break;
case PROJECTED_THROUGH_TOK:
child = new PMProjectedThrough( m_pPart );
error = !parseProjectedThrough( ( PMProjectedThrough* ) child );
break;
case TEXTURE_TOK:
child = new PMTexture( m_pPart );
error = !parseTexture( ( PMTexture* ) child );
break;
case AGATE_TOK:
case AVERAGE_TOK:
case BOXED_TOK:
case BOZO_TOK:
case BUMPS_TOK:
case CELLS_TOK:
case CRACKLE_TOK:
case CYLINDRICAL_TOK:
case DENTS_TOK:
case DENSITY_FILE_TOK:
case GRADIENT_TOK:
case GRANITE_TOK:
case JULIA_TOK:
case LEOPARD_TOK:
case MAGNET_TOK:
case MANDEL_TOK:
case MARBLE_TOK:
case ONION_TOK:
case PLANAR_TOK:
case QUILTED_TOK:
case RADIAL_TOK:
case RIPPLES_TOK:
case SLOPE_TOK:
case SPHERICAL_TOK:
case SPIRAL1_TOK:
case SPIRAL2_TOK:
case SPOTTED_TOK:
case WOOD_TOK:
case WAVES_TOK:
case WRINKLES_TOK:
child = new PMPattern( m_pPart );
{
bool normal = true;
if( parent && ( parent->type( ) != "Normal" ) )
normal = false;
error = !parsePattern( ( PMPattern* ) child, normal );
}
break;
case TURBULENCE_TOK:
// Search for a PMPattern in the object's children
child = parent->firstChild( );
while( child && !child->isA( "Pattern" ) )
child = child->nextSibling( );
if( child )
{
error = !parsePattern( ( PMPattern* ) child );
child = 0;
noChild = true;
}
else
{
printError( i18n( "Found turbulence without a pattern." ) );
error = true;
}
break;
case FREQUENCY_TOK:
case PHASE_TOK:
case RAMP_WAVE_TOK:
case TRIANGLE_WAVE_TOK:
case SINE_WAVE_TOK:
case SCALLOP_WAVE_TOK:
case CUBIC_WAVE_TOK:
case POLY_WAVE_TOK:
// Search for a PMBlendMapModifiers in the object's children
child = parent->firstChild( );
while( child && !child->isA( "BlendMapModifiers" ) )
child = child->nextSibling( );
if( child )
{
error = !parseBlendMapModifiers( ( PMBlendMapModifiers* ) child );
child = 0;
noChild = 0;
}
else
{
child = new PMBlendMapModifiers( m_pPart );
error = !parseBlendMapModifiers( ( PMBlendMapModifiers* ) child );
}
break;
case WARP_TOK:
child = new PMWarp( m_pPart );
error = !parseWarp( ( PMWarp* ) child );
break;
case PIGMENT_TOK:
child = new PMPigment( m_pPart );
error = !parsePigment( ( PMPigment* ) child );
break;
case NORMAL_TOK:
child = new PMNormal( m_pPart );
error = !parseNormal( ( PMNormal* ) child );
break;
case NORMAL_MAP_TOK:
child = new PMNormalMap( m_pPart );
error = !parseNormalMap( ( PMNormalMap* ) child );
break;
case BUMP_MAP_TOK:
child = new PMBumpMap( m_pPart );
error = !parseBumpMap( ( PMBumpMap* ) child );
break;
case SLOPE_MAP_TOK:
child = new PMSlopeMap( m_pPart );
error = !parseSlopeMap( ( PMSlopeMap* ) child );
break;
case DENSITY_MAP_TOK:
child = new PMDensityMap( m_pPart );
error = !parseDensityMap( ( PMDensityMap* ) child );
break;
case TEXTURE_MAP_TOK:
child = new PMTextureMap( m_pPart );
error = !parseTextureMap( ( PMTextureMap* ) child );
break;
case MATERIAL_MAP_TOK:
child = new PMMaterialMap( m_pPart );
error = !parseMaterialMap( ( PMMaterialMap* ) child );
break;
case PIGMENT_MAP_TOK:
child = new PMPigmentMap( m_pPart );
error = !parsePigmentMap( ( PMPigmentMap* ) child );
break;
case COLOR_MAP_TOK:
case COLOUR_MAP_TOK:
child = new PMColorMap( m_pPart );
error = !parseColorMap( ( PMColorMap* ) child );
break;
case CHECKER_TOK:
case HEXAGON_TOK:
case BRICK_TOK:
{
bool normal = false;
double depth = 0.0;
int expect = 0;
PMListPattern::PMListType type = PMListPattern::ListPatternChecker;
if( parent && parent->type( ) == "Normal" )
normal = true;
else if( m_pTopParent && m_pTopParent->type( ) == "Normal" )
normal = true;
switch( m_token )
{
case CHECKER_TOK:
type = PMListPattern::ListPatternChecker;
expect = 2;
break;
case HEXAGON_TOK:
type = PMListPattern::ListPatternHexagon;
expect = 3;
break;
case BRICK_TOK:
type = PMListPattern::ListPatternBrick;
expect = 2;
break;
}
nextToken( );
if( normal )
{
child = new PMNormalList( m_pPart );
if( parseFloat( depth, true ) )
( ( PMNormalList* ) child )->setDepth( depth );
if( m_token == NORMAL_TOK )
error = !parseNormalList( ( PMNormalList* ) child, expect );
}
else
{
switch( m_token )
{
case COLOR_TOK:
case COLOUR_TOK:
case RGB_TOK:
case RGBT_TOK:
case RGBF_TOK:
case RGBFT_TOK:
case RED_TOK:
case GREEN_TOK:
case BLUE_TOK:
case TRANSMIT_TOK:
case FILTER_TOK:
case ID_TOK:
child = new PMColorList( m_pPart );
error = !parseColorList( ( PMColorList* ) child, expect );
break;
case PIGMENT_TOK:
child = new PMPigmentList( m_pPart );
error = !parsePigmentList( ( PMPigmentList* ) child, expect );
break;
case TEXTURE_TOK:
child = new PMTextureList( m_pPart );
error = !parseTextureList( ( PMTextureList* ) child, expect );
break;
case NORMAL_TOK:
child = new PMNormalList( m_pPart );
error = !parseNormalList( ( PMNormalList* ) child, expect );
break;
case DENSITY_TOK:
child = new PMDensityList( m_pPart );
error = !parseDensityList( ( PMDensityList* ) child, expect );
break;
default:
printError( i18n( "Invalid list member." ) );
error = true;
}
}
if( child )
{
( ( PMListPattern* ) child )->setListType( type );
int oldConsumed;
double num = 0;
PMVector vector;
do
{
oldConsumed = m_consumedTokens;
switch( m_token )
{
case MORTAR_TOK:
nextToken( );
if( !parseFloat( num ) )
return false;
( ( PMListPattern* ) child )->setMortar( num );
break;
case BRICK_SIZE_TOK:
nextToken( );
if( !parseVector( vector ) )
return false;
( ( PMListPattern* ) child )->setBrickSize( vector );
break;
default:
break;
}
}
while( oldConsumed != m_consumedTokens );
}
break;
}
case IMAGE_MAP_TOK:
child = new PMImageMap( m_pPart );
error = !parseImageMap( ( PMImageMap* ) child );
break;
case FINISH_TOK:
child = new PMFinish( m_pPart );
error = !parseFinish( ( PMFinish* ) child );
break;
case INTERIOR_TOK:
child = new PMInterior( m_pPart );
error = !parseInterior( ( PMInterior* ) child );
break;
case MEDIA_TOK:
child = new PMMedia( m_pPart );
error = !parseMedia( ( PMMedia* ) child );
break;
case DENSITY_TOK:
child = new PMDensity( m_pPart );
error = !parseDensity( ( PMDensity* ) child );
break;
case MATERIAL_TOK:
child = new PMMaterial( m_pPart );
error = !parseMaterial( ( PMMaterial* ) child );
break;
case SKY_SPHERE_TOK:
child = new PMSkySphere( m_pPart );
error = !parseSkySphere( ( PMSkySphere* ) child );
break;
case RAINBOW_TOK:
child = new PMRainbow( m_pPart );
error = !parseRainbow( ( PMRainbow* ) child );
break;
case FOG_TOK:
child = new PMFog( m_pPart );
error = !parseFog( ( PMFog* ) child );
break;
case GLOBAL_SETTINGS_TOK:
child = new PMGlobalSettings( m_pPart );
error = !parseGlobalSettings( ( PMGlobalSettings* ) child );
break;
case SCALE_TOK:
child = new PMScale( m_pPart );
error = !parseScale( ( PMScale* ) child );
break;
case ROTATE_TOK:
child = new PMRotate( m_pPart );
error = !parseRotate( ( PMRotate* ) child );
break;
case TRANSLATE_TOK:
child = new PMTranslate( m_pPart );
error = !parseTranslate( ( PMTranslate* ) child );
break;
case MATRIX_TOK:
child = new PMPovrayMatrix( m_pPart );
error = !parseMatrix( ( PMPovrayMatrix* ) child );
break;
case BOUNDED_BY_TOK:
if( parent && ( parent->type( ) == "ClippedBy" ) )
finished = true;
else
{
child = new PMBoundedBy( m_pPart );
error = !parseBoundedBy( ( PMBoundedBy* ) child );
}
break;
case CLIPPED_BY_TOK:
if( parent && ( parent->type( ) == "BoundedBy" ) )
finished = true;
else
{
child = new PMClippedBy( m_pPart );
error = !parseClippedBy( ( PMClippedBy* ) child );
}
break;
case ISOSURFACE_TOK:
child = new PMIsoSurface( m_pPart );
error = !parseIsoSurface( ( PMIsoSurface* ) child );
break;
case RADIOSITY_TOK:
child = new PMRadiosity( m_pPart );
error = !parseRadiosity( ( PMRadiosity* ) child );
break;
case PHOTONS_TOK:
if ( parent && ( parent->type( ) == "GlobalSettings" ) )
{
child = new PMGlobalPhotons( m_pPart );
error = !parseGlobalPhotons( ( PMGlobalPhotons* ) child );
}
else
{
child = new PMPhotons( m_pPart );
error =!parsePhotons( ( PMPhotons* ) child );
}
break;
case LIGHT_GROUP_TOK:
child = new PMLightGroup( m_pPart );
error = !parseLightGroup( ( PMLightGroup* ) child );
break;
case INTERIOR_TEXTURE_TOK:
child = new PMInteriorTexture( m_pPart );
error = !parseInteriorTexture( ( PMInteriorTexture* ) child );
break;
case SPHERE_SWEEP_TOK:
child = new PMSphereSweep( m_pPart );
error = !parseSphereSweep( ( PMSphereSweep* ) child );
break;
case MESH_TOK:
child = new PMMesh( m_pPart );
error = !parseMesh( ( PMMesh* ) child );
break;
case DECLARE_TOK:
nextToken( );
if( m_token == ID_TOK )
{
TQString id( m_pScanner->sValue( ) );
nextToken( );
if( !parseToken( '=' ) )
error = true;
else
{
PMValue v;
switch( m_token )
{
case OBJECT_TOK:
// finite solid
case BLOB_TOK:
case BOX_TOK:
case CONE_TOK:
case CYLINDER_TOK:
case HEIGHT_FIELD_TOK:
case JULIA_FRACTAL_TOK:
case LATHE_TOK:
case PRISM_TOK:
case SPHERE_TOK:
case SUPERELLIPSOID_TOK:
case SOR_TOK:
case TEXT_TOK:
case TORUS_TOK:
case ISOSURFACE_TOK:
case SPHERE_SWEEP_TOK:
// finite patch
case BICUBIC_PATCH_TOK:
case DISC_TOK:
case MESH_TOK:
case POLYGON_TOK:
case TRIANGLE_TOK:
case SMOOTH_TRIANGLE_TOK:
// infinite solid
case PLANE_TOK:
case QUADRIC_TOK:
case CUBIC_TOK:
case QUARTIC_TOK:
case POLY_TOK:
// csg
case UNION_TOK:
case INTERSECTION_TOK:
case DIFFERENCE_TOK:
case MERGE_TOK:
// textures
case TEXTURE_TOK:
case INTERIOR_TEXTURE_TOK:
case PIGMENT_TOK:
case NORMAL_TOK:
case FINISH_TOK:
case TEXTURE_MAP_TOK:
case PIGMENT_MAP_TOK:
case COLOR_MAP_TOK:
case COLOUR_MAP_TOK:
case NORMAL_MAP_TOK:
case SLOPE_MAP_TOK:
case DENSITY_MAP_TOK:
case INTERIOR_TOK:
case MEDIA_TOK:
case DENSITY_TOK:
case MATERIAL_TOK:
case SKY_SPHERE_TOK:
case RAINBOW_TOK:
case FOG_TOK:
// misc
case LIGHT_SOURCE_TOK:
case LIGHT_GROUP_TOK:
child = new PMDeclare( m_pPart );
error = !parseDeclare( ( PMDeclare* ) child );
break;
default:
// constant, vector or color declare?
if( parseNumericExpression( v ) )
{
checkID( id, v );
noChild = true;
}
else
error = true;
break;
}
}
if( child )
if( child->isA( "Declare" ) )
( ( PMDeclare* ) child )->setID( id );
if( m_token == ';' )
nextToken( );
}
else
printExpected( i18n( "identifier" ), m_pScanner->sValue( ) );
break;
case OBJECT_TOK:
error = !parseObject( parent );
noChild = true;
break;
case RAW_POVRAY_TOK:
child = new PMRaw( m_pPart, m_pScanner->sValue( ) );
error = false;
nextToken( );
break;
default:
finished = true;
break;
}
}
if( !finished && !child && !noChild )
error = true;
if( child )
{
if( !insertChild( child, parent ) )
{
delete child;
child = 0;
}
else if( child->isA( "Declare" ) )
checkID( ( PMDeclare* ) child );
numParsed ++;
if( ( max > 0 ) && ( numParsed >= max ) )
finished = true;
}
}
while( !finished && !error );
return finished;
}
bool PMPovrayParser::parseToken( int t, const TQString& tokenName )
{
if( t == ',' )
{
// do not require commas any more.
if( m_token == ',' )
nextToken( );
return true;
}
else if( m_token == t )
{
nextToken( );
return true;
}
if( tokenName.isNull() )
printExpected( ( char ) t, m_pScanner->sValue( ) );
else
printExpected( tokenName, m_pScanner->sValue( ) );
return false;
}
bool PMPovrayParser::parseNumericItem( PMValue& v, bool checkForBool /*=false*/ )
{
bool finishColor = false;
PMVector cv( 0 );
PMVector vec( 0 );
PMValue hv;
PMSymbol* s;
int i;
switch( m_token )
{
case X_TOK:
v.setVector( PMVector( 1.0, 0.0, 0.0 ) );
nextToken( );
break;
case Y_TOK:
v.setVector( PMVector( 0.0, 1.0, 0.0 ) );
nextToken( );
break;
case Z_TOK:
v.setVector( PMVector( 0.0, 0.0, 1.0 ) );
nextToken( );
break;
case T_TOK:
v.setVector( PMVector( 0.0, 0.0, 0.0, 1.0 ) );
nextToken( );
break;
case U_TOK:
v.setVector( PMVector( 1.0, 0.0 ) );
nextToken( );
break;
case V_TOK:
v.setVector( PMVector( 0.0, 1.0 ) );
nextToken( );
break;
case PI_TOK:
v.setFloat( 3.1415926535897932384626 );
nextToken( );
break;
case CLOCK_TOK:
printMessage( PMMClockDefault );
v.setFloat( 0.0 );
break;
case CLOCK_DELTA_TOK:
printMessage( PMMClockDeltaDefault );
v.setFloat( 1.0 );
break;
case FLOAT_TOK:
v.setFloat( m_pScanner->fValue( ) );
nextToken( );
break;
case INTEGER_TOK:
v.setFloat( ( double ) m_pScanner->iValue( ) );
nextToken( );
break;
case ON_TOK:
case TRUE_TOK:
case YES_TOK:
v.setFloat( 1.0 );
nextToken( );
break;
case OFF_TOK:
case FALSE_TOK:
case NO_TOK:
v.setFloat( 0.0 );
nextToken( );
break;
case '(':
nextToken( );
if( !parseNumericExpression( v ) )
return false;
if( !parseToken( ')' ) )
return false;
break;
case '-':
nextToken( );
if( !parseNumericItem( v ) )
return false;
if( v.type( ) == PMVFloat )
v.setFloat( -v.floatValue( ) );
else
v.setVector( -v.vector( ) );
break;
case '+':
nextToken( );
if( !parseNumericItem( v ) )
return false;
break;
case '<':
if( !parseVectorLiteral( vec ) )
return false;
v.setVector( vec );
break;
case COLOR_TOK:
case COLOUR_TOK:
nextToken( );
case RGB_TOK:
case RGBT_TOK:
case RGBF_TOK:
case RGBFT_TOK:
case RED_TOK:
case GREEN_TOK:
case BLUE_TOK:
case TRANSMIT_TOK:
case FILTER_TOK:
cv.resize( 5 );
cv = 0.0;
finishColor = true;
break;
case ID_TOK:
s = getSymbol( m_pScanner->sValue( ) );
if( s )
{
nextToken( );
if( s->type( ) == PMSymbol::Value )
v = s->value( );
else
{
printError( i18n( "Float, color or vector identifier expected." ) );
return false;
}
}
else
{
printError( i18n( "Undefined identifier \"%1\"." )
.arg( m_pScanner->sValue( ) ) );
nextToken( );
}
break;
default:
if( !checkForBool )
printUnexpected( m_pScanner->sValue( ) );
return false;
break;
}
if( !finishColor )
{
if( m_token == '.' )
{
int index = -1;
nextToken( );
switch( m_token )
{
case X_TOK:
case RED_TOK:
case U_TOK:
index = 0;
break;
case Y_TOK:
case GREEN_TOK:
case V_TOK:
index = 1;
break;
case Z_TOK:
case BLUE_TOK:
index = 2;
break;
case T_TOK:
case FILTER_TOK:
index = 3;
break;
case TRANSMIT_TOK:
index = 4;
break;
default:
break;
}
if( index >= 0 )
{
nextToken( );
if( v.type( ) == PMVFloat )
{
if( index != 0 )
index = -1;
}
else
{
PMVector vec;
if( v.type( ) == PMVVector )
vec = v.vector( );
else
vec = v.color( );
if( ( ( unsigned ) index ) < vec.size( ) )
v.setFloat( vec[index] );
else
index = -1;
}
}
if( index == -1 )
{
printError( i18n( "Bad operands for period operator." ) );
return false;
}
}
}
while( finishColor )
{
switch( m_token )
{
case RGB_TOK:
nextToken( );
if( !parseNumericExpression( hv ) )
return false;
switch( hv.type( ) )
{
case PMVFloat:
cv[0] = hv.floatValue( );
cv[1] = hv.floatValue( );
cv[2] = hv.floatValue( );
break;
case PMVVector:
vec = hv.vector( );
vec.resize( 3 );
cv[0] = vec[0];
cv[1] = vec[1];
cv[2] = vec[2];
break;
default:
printError( i18n( "Float or vector expression expected" ) );
break;
}
break;
case RGBT_TOK:
nextToken( );
if( !parseNumericExpression( hv ) )
return false;
switch( hv.type( ) )
{
case PMVFloat:
cv[0] = hv.floatValue( );
cv[1] = hv.floatValue( );
cv[2] = hv.floatValue( );
cv[4] = hv.floatValue( );
break;
case PMVVector:
vec = hv.vector( );
vec.resize( 4 );
cv[0] = vec[0];
cv[1] = vec[1];
cv[2] = vec[2];
cv[4] = vec[3];
break;
default:
printError( i18n( "Float or vector expression expected" ) );
break;
}
break;
case RGBF_TOK:
nextToken( );
if( !parseNumericExpression( hv ) )
return false;
switch( hv.type( ) )
{
case PMVFloat:
cv[0] = hv.floatValue( );
cv[1] = hv.floatValue( );
cv[2] = hv.floatValue( );
cv[3] = hv.floatValue( );
break;
case PMVVector:
vec = hv.vector( );
vec.resize( 4 );
cv[0] = vec[0];
cv[1] = vec[1];
cv[2] = vec[2];
cv[3] = vec[3];
break;
default:
printError( i18n( "Float or vector expression expected" ) );
break;
}
break;
case RGBFT_TOK:
nextToken( );
if( !parseNumericExpression( hv ) )
return false;
switch( hv.type( ) )
{
case PMVFloat:
cv = hv.floatValue( );
break;
case PMVVector:
vec = hv.vector( );
vec.resize( 5 );
cv = vec;
break;
default:
printError( i18n( "Float or vector expression expected" ) );
break;
}
break;
case RED_TOK:
nextToken( );
parseNumericExpression( hv );
if( hv.type( ) != PMVFloat )
{
printError( i18n( "Float expression expected" ) );
break;
}
cv[0] = hv.floatValue( );
break;
case GREEN_TOK:
nextToken( );
parseNumericExpression( hv );
if( hv.type( ) != PMVFloat )
{
printError( i18n( "Float expression expected" ) );
break;
}
cv[1] = hv.floatValue( );
break;
case BLUE_TOK:
nextToken( );
parseNumericExpression( hv );
if( hv.type( ) != PMVFloat )
{
printError( i18n( "Float expression expected" ) );
break;
}
cv[2] = hv.floatValue( );
break;
case FILTER_TOK:
case ALPHA_TOK:
nextToken( );
parseNumericExpression( hv );
if( hv.type( ) != PMVFloat )
{
printError( i18n( "Float expression expected" ) );
break;
}
cv[3] = hv.floatValue( );
break;
case TRANSMIT_TOK:
nextToken( );
parseNumericExpression( hv );
if( hv.type( ) != PMVFloat )
{
printError( i18n( "Float expression expected" ) );
break;
}
cv[4] = hv.floatValue( );
break;
case ID_TOK:
if( parseNumericItem( hv ) )
{
if( hv.type( ) == PMVFloat )
{
for( i = 0; i < 5; i++ )
cv[i] = hv.floatValue( );
}
else if( hv.type( ) == PMVVector )
{
cv = hv.vector( );
cv.resize( 5 );
}
else
cv = hv.color( );
}
break;
default:
finishColor = false;
v.setColor( cv );
break;
}
}
return true;
}
bool PMPovrayParser::parseVectorLiteral( PMVector& p )
{
PMValue v;
if( !parseToken( '<' ) )
return false;
if( !parseNumericExpression( v ) )
return false;
if( v.type( ) != PMVFloat )
{
printError( i18n( "Float expression expected" ) );
return false;
}
p.resize( 1 );
p[0] = v.floatValue( );
while( m_token != '>' )
{
// many old scenes do not use a comma between values
if( m_token == ',' )
nextToken( );
// parseToken( ',' );
if( !parseNumericExpression( v ) )
return false;
if( v.type( ) != PMVFloat )
{
printError( i18n( "Float expression expected" ) );
return false;
}
p.resize( p.size( ) + 1 );
p[p.size( ) - 1] = v.floatValue( );
}
/** old code
while( m_token == ',' )
{
nextToken( );
if( !parseNumericExpression( v ) )
return false;
if( v.type( ) != PMVFloat )
{
printError( i18n( "Float expression expected" ) );
return false;
}
p.resize( p.size( ) + 1 );
p[p.size( ) - 1] = v.floatValue( );
}
*/
if( !parseToken( '>' ) )
return false;
return true;
}
bool PMPovrayParser::parseNumericExpression( PMValue& v, bool checkForBool /*=false*/ )
{
bool end = false;
PMValue v2;
PMVector hv( 0 );
if( !parseNumericItem( v, checkForBool ) )
return false;
do
{
switch( m_token )
{
case '*':
nextToken( );
if( !parseNumericItem( v2 ) )
break;
switch( v.type( ) )
{
case PMVFloat:
switch( v2.type( ) )
{
case PMVFloat:
v.setFloat( v.floatValue( ) * v2.floatValue( ) );
break;
case PMVVector:
v.setVector( v2.vector( ) * v.floatValue( ) );
break;
case PMVColor:
v.setColor( v2.color( ) * v.floatValue( ) );
break;
}
break;
case PMVVector:
switch( v2.type( ) )
{
case PMVFloat:
v.setVector( v.vector( ) * v2.floatValue( ) );
break;
case PMVVector:
v.setVector( v.vector( ) * v2.vector( ) );
break;
case PMVColor:
if( v.vector( ).size( ) == 5 )
v.setColor( v.vector( ) * v2.color( ) );
else
printError( i18n( "You can't multiply a vector with a color" ) );
break;
}
break;
case PMVColor:
switch( v2.type( ) )
{
case PMVFloat:
v.setColor( v.color( ) * v2.floatValue( ) );
break;
case PMVVector:
if( v2.vector( ).size( ) == 5 )
v.setColor( v2.vector( ) * v.color( ) );
else
printError( i18n( "You can't multiply a vector with a color" ) );
break;
case PMVColor:
v.setColor( v.color( ) * v2.color( ) );
break;
}
break;
}
break;
case '/':
nextToken( );
if( !parseNumericItem( v2 ) )
break;
switch( v.type( ) )
{
case PMVFloat:
switch( v2.type( ) )
{
case PMVFloat:
v.setFloat( v.floatValue( ) / v2.floatValue( ) );
break;
case PMVVector:
hv.resize( v2.vector( ).size( ) );
hv = v.floatValue( );
v.setVector( hv / v2.vector( ) );
break;
case PMVColor:
hv.resize( 5 );
hv = v.floatValue( );
v.setColor( hv / v.floatValue( ) );
break;
}
break;
case PMVVector:
switch( v2.type( ) )
{
case PMVFloat:
v.setVector( v.vector( ) / v2.floatValue( ) );
break;
case PMVVector:
v.setVector( v.vector( ) / v2.vector( ) );
break;
case PMVColor:
if( v.vector( ).size( ) == 5 )
v.setColor( v.vector( ) / v2.color( ) );
else
printError( i18n( "You can't divide a vector by a color" ) );
break;
}
break;
case PMVColor:
switch( v2.type( ) )
{
case PMVFloat:
v.setColor( v.color( ) / v2.floatValue( ) );
break;
case PMVVector:
if( v2.vector( ).size( ) == 5 )
v.setColor( v2.vector( ) / v.color( ) );
else
printError( i18n( "You can't divide a color by a vector" ) );
break;
case PMVColor:
v.setColor( v.color( ) / v2.color( ) );
break;
}
break;
}
break;
case '+':
nextToken( );
if( !parseNumericExpression( v2 ) )
break;
switch( v.type( ) )
{
case PMVFloat:
switch( v2.type( ) )
{
case PMVFloat:
v.setFloat( v.floatValue( ) + v2.floatValue( ) );
break;
case PMVVector:
v.setVector( v2.vector( ) + v.floatValue( ) );
break;
case PMVColor:
v.setColor( v2.color( ) + v.floatValue( ) );
break;
}
break;
case PMVVector:
switch( v2.type( ) )
{
case PMVFloat:
v.setVector( v.vector( ) + v2.floatValue( ) );
break;
case PMVVector:
v.setVector( v.vector( ) + v2.vector( ) );
break;
case PMVColor:
if( v.vector( ).size( ) == 5 )
v.setColor( v.vector( ) + v2.color( ) );
else
printError( i18n( "You can't add a vector and a color" ) );
break;
}
break;
case PMVColor:
switch( v2.type( ) )
{
case PMVFloat:
v.setColor( v.color( ) + v2.floatValue( ) );
break;
case PMVVector:
if( v2.vector( ).size( ) == 5 )
v.setColor( v2.vector( ) + v.color( ) );
else
printError( i18n( "You can't add a vector with a color" ) );
break;
case PMVColor:
v.setColor( v.color( ) + v2.color( ) );
break;
}
break;
}
break;
case '-':
nextToken( );
if( !parseNumericExpression( v2 ) )
break;
switch( v.type( ) )
{
case PMVFloat:
switch( v2.type( ) )
{
case PMVFloat:
v.setFloat( v.floatValue( ) - v2.floatValue( ) );
break;
case PMVVector:
v.setVector( v2.vector( ) - v.floatValue( ) );
break;
case PMVColor:
v.setColor( v2.color( ) - v.floatValue( ) );
break;
}
break;
case PMVVector:
switch( v2.type( ) )
{
case PMVFloat:
v.setVector( v.vector( ) - v2.floatValue( ) );
break;
case PMVVector:
v.setVector( v.vector( ) - v2.vector( ) );
break;
case PMVColor:
if( v.vector( ).size( ) == 5 )
v.setColor( v.vector( ) - v2.color( ) );
else
printError( i18n( "You can't subtract a vector and a color" ) );
break;
}
break;
case PMVColor:
switch( v2.type( ) )
{
case PMVFloat:
v.setColor( v.color( ) - v2.floatValue( ) );
break;
case PMVVector:
if( v2.vector( ).size( ) == 5 )
v.setColor( v2.vector( ) - v.color( ) );
else
printError( i18n( "You can't subtract a vector and a color" ) );
break;
case PMVColor:
v.setColor( v.color( ) - v2.color( ) );
break;
}
break;
}
break;
default:
end = true;
break;
}
}
while( !end );
return true;
}
bool PMPovrayParser::parseVector( PMVector& vector, unsigned int size )
{
PMValue v;
unsigned int i;
if( !parseNumericExpression( v ) )
return false;
switch( v.type( ) )
{
case PMVFloat:
vector.resize( size );
for( i = 0; i < size; i++ )
vector[i] = v.floatValue( );
break;
case PMVVector:
vector = v.vector( );
vector.resize( size );
break;
default:
printError( i18n( "Float or vector expression expected" ) );
return false;
}
return true;
}
bool PMPovrayParser::parseFloat( double& d, bool suppressError )
{
PMValue v;
if( !parseNumericExpression( v, suppressError ) )
return false;
switch( v.type( ) )
{
case PMVFloat:
d = v.floatValue( );
break;
case PMVVector:
d = ( v.vector( ) )[0];
break;
default:
printError( i18n( "Float expression expected" ) );
return false;
}
return true;
}
bool PMPovrayParser::parseInt( int& i )
{
double d;
if( !parseFloat( d ) )
return false;
i = ( int ) ( d + 0.5 );
return true;
}
bool PMPovrayParser::parseColor( PMColor& c )
{
PMValue v;
if( !parseNumericExpression( v ) )
return false;
if( v.type( ) == PMVColor )
c = PMColor( v.color( ) );
else if( v.type( ) == PMVVector )
{
if( v.vector( ).size( ) == 5 )
c = PMColor( v.vector( ) );
else
{
printError( i18n( "Color expression expected" ) );
return false;
}
}
else if( v.type( ) == PMVFloat )
{
double d = v.floatValue( );
c = PMColor( d, d, d, d, d );
}
else
{
printError( i18n( "Color expression expected" ) );
return false;
}
return true;
}
bool PMPovrayParser::parseObjectModifiers( PMGraphicalObject* o )
{
bool finished = false;
PMSolidObject* so = 0;
if( o->isA( "SolidObject" ) )
so = ( PMSolidObject* ) o;
do
{
finished = true;
switch( m_token )
{
case NO_SHADOW_TOK:
o->setNoShadow( true );
nextToken( );
finished = false;
break;
case NO_IMAGE_TOK:
o->setNoImage( true );
nextToken( );
finished = false;
break;
case NO_REFLECTION_TOK:
o->setNoReflection( true );
nextToken( );
finished = false;
break;
case DOUBLE_ILLUMINATE_TOK:
o->setDoubleIlluminate( true );
nextToken( );
finished = false;
break;
default:
break;
}
if( so )
{
switch( m_token )
{
case HOLLOW_TOK:
so->setHollow( PMTrue );
nextToken( );
if( isTrue( ) )
nextToken( );
else if( isFalse( ) )
{
nextToken( );
so->setHollow( PMFalse );
}
finished = false;
break;
case INVERSE_TOK:
so->setInverse( true );
nextToken( );
finished = false;
break;
default:
break;
}
}
}
while( !finished );
return true;
}
bool PMPovrayParser::parseCSG( PMCSG* pNewCSG )
{
int oldConsumed;
switch( m_token )
{
case UNION_TOK:
pNewCSG->setCSGType( PMCSG::CSGUnion );
break;
case INTERSECTION_TOK:
pNewCSG->setCSGType( PMCSG::CSGIntersection );
break;
case DIFFERENCE_TOK:
pNewCSG->setCSGType( PMCSG::CSGDifference );
break;
case MERGE_TOK:
pNewCSG->setCSGType( PMCSG::CSGMerge );
break;
default:
printUnexpected( m_pScanner->sValue( ) );
return false;
break;
}
nextToken( );
if( !parseToken( '{' ) )
return false;
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( pNewCSG );
parseObjectModifiers( pNewCSG );
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseBox( PMBox* pNewBox )
{
PMVector vector;
int oldConsumed;
if( !parseToken( BOX_TOK, "box" ) )
return false;
if( !parseToken( '{' ) )
return false;
if( !parseVector( vector ) )
return false;
pNewBox->setCorner1( vector );
if( !parseToken( ',' ) )
return false;
if( !parseVector( vector ) )
return false;
pNewBox->setCorner2( vector );
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( pNewBox );
parseObjectModifiers( pNewBox );
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseSphere( PMSphere* pNewSphere )
{
PMVector vector;
double radius;
int oldConsumed;
if( !parseToken( SPHERE_TOK, "sphere" ) )
return false;
if( !parseToken( '{' ) )
return false;
if( !parseVector( vector ) )
return false;
pNewSphere->setCentre( vector );
if( !parseToken( ',' ) )
return false;
if( !parseFloat( radius ) )
return false;
pNewSphere->setRadius( radius );
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( pNewSphere );
parseObjectModifiers( pNewSphere );
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseCylinder( PMCylinder* pNewCyl )
{
PMVector vector;
double radius;
int oldConsumed;
if( !parseToken( CYLINDER_TOK, "cylinder" ) )
return false;
if( !parseToken( '{' ) )
return false;
if( !parseVector( vector ) )
return false;
pNewCyl->setEnd1( vector );
if( !parseToken( ',' ) )
return false;
if( !parseVector( vector ) )
return false;
pNewCyl->setEnd2( vector );
if( !parseToken( ',' ) )
return false;
if( !parseFloat(radius) )
return false;
pNewCyl->setRadius( radius );
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( pNewCyl );
parseObjectModifiers( pNewCyl );
switch( m_token )
{
case OPEN_TOK:
nextToken( );
pNewCyl->setOpen( true );
}
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseCone( PMCone* pNewCone )
{
PMVector vector;
double radius;
int oldConsumed;
if( !parseToken( CONE_TOK, "cone" ) )
return false;
if( !parseToken( '{' ) )
return false;
if( !parseVector( vector ) )
return false;
pNewCone->setEnd1( vector );
if( !parseToken( ',' ) )
return false;
if( !parseFloat( radius ) )
return false;
pNewCone->setRadius1( radius );
if( !parseToken( ',' ) )
return false;
if( !parseVector( vector ) )
return false;
pNewCone->setEnd2( vector );
if( !parseToken( ',' ) )
return false;
if( !parseFloat( radius ) )
return false;
pNewCone->setRadius2( radius );
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( pNewCone );
parseObjectModifiers( pNewCone );
switch( m_token )
{
case OPEN_TOK:
nextToken( );
pNewCone->setOpen( true );
}
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseTorus( PMTorus* pNewTorus )
{
double radius;
int oldConsumed;
if( !parseToken( TORUS_TOK, "torus" ) )
return false;
if( !parseToken( '{' ) )
return false;
if( !parseFloat( radius ) )
return false;
pNewTorus->setMajorRadius( radius );
if( !parseToken( ',' ) )
return false;
if( !parseFloat( radius ) )
return false;
pNewTorus->setMinorRadius( radius );
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( pNewTorus );
parseObjectModifiers( pNewTorus );
switch( m_token )
{
case STURM_TOK:
nextToken( );
pNewTorus->setSturm( true );
}
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseBlob( PMBlob* pNewBlob )
{
PMVector vector;
double threshold;
int oldConsumed;
if( !parseToken( BLOB_TOK, "blob" ) )
return false;
if( !parseToken( '{' ) )
return false;
pNewBlob->setThreshold( 1.0 );
do
{
oldConsumed = m_consumedTokens;
switch( m_token )
{
case STURM_TOK:
nextToken( );
pNewBlob->setSturm( true );
break;
case HIERARCHY_TOK:
pNewBlob->setHierarchy( true );
nextToken( );
if( isTrue( ) )
nextToken( );
else if( isFalse( ) )
{
nextToken( );
pNewBlob->setHierarchy( false );
}
break;
case THRESHOLD_TOK:
nextToken( );
if( parseFloat( threshold ) )
{
if( threshold <= 0 )
printError( i18n( "The threshold value has to be positive" ) );
else
pNewBlob->setThreshold( threshold );
}
break;
}
parseChildObjects( pNewBlob );
parseObjectModifiers( pNewBlob );
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseBlobSphere( PMBlobSphere* pNewBlobSphere )
{
PMVector vector;
double radius;
double strength;
int oldConsumed;
if( !parseToken( SPHERE_TOK, "sphere" ) )
return false;
if( !parseToken( '{' ) )
return false;
if( !parseVector( vector ) )
return false;
pNewBlobSphere->setCentre( vector );
if( !parseToken( ',' ) )
return false;
if( !parseFloat( radius ) )
return false;
pNewBlobSphere->setRadius( radius );
if( !parseToken( ',' ) )
return false;
if( m_token == STRENGTH_TOK )
nextToken( );
if( !parseFloat( strength ) )
return false;
pNewBlobSphere->setStrength( strength );
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( pNewBlobSphere );
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseBlobComponent( PMBlobSphere* pNewBlobSphere )
{
PMVector vector;
double radius;
double strength;
if( !parseToken( COMPONENT_TOK, "component" ) )
return false;
if( !parseFloat( strength ) )
return false;
pNewBlobSphere->setStrength( strength );
if( !parseToken( ',' ) )
return false;
if( !parseFloat( radius ) )
return false;
pNewBlobSphere->setRadius( radius );
if( !parseToken( ',' ) )
return false;
if( !parseVector( vector ) )
return false;
pNewBlobSphere->setCentre( vector );
return true;
}
bool PMPovrayParser::parseBlobCylinder( PMBlobCylinder* pNewBlobCylinder )
{
PMVector vector;
double radius;
double strength;
int oldConsumed;
if( !parseToken( CYLINDER_TOK, "cylinder" ) )
return false;
if( !parseToken( '{' ) )
return false;
if( !parseVector( vector ) )
return false;
pNewBlobCylinder->setEnd1( vector );
if( !parseToken( ',' ) )
return false;
if( !parseVector( vector ) )
return false;
pNewBlobCylinder->setEnd2( vector );
if( !parseToken( ',' ) )
return false;
if( !parseFloat( radius ) )
return false;
pNewBlobCylinder->setRadius( radius );
if( !parseToken( ',' ) )
return false;
if( m_token == STRENGTH_TOK )
nextToken( );
if( !parseFloat( strength ) )
return false;
pNewBlobCylinder->setStrength( strength );
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( pNewBlobCylinder );
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseHeightField( PMHeightField* pNewHeightField )
{
int oldConsumed;
double wl;
if( !parseToken( HEIGHT_FIELD_TOK, "height_field" ) )
return false;
if( !parseToken( '{' ) )
return false;
switch( m_token )
{
case GIF_TOK:
pNewHeightField->setHeightFieldType( PMHeightField::HFgif );
nextToken( );
break;
case TGA_TOK:
pNewHeightField->setHeightFieldType( PMHeightField::HFtga );
nextToken( );
break;
case POT_TOK:
pNewHeightField->setHeightFieldType( PMHeightField::HFpot );
nextToken( );
break;
case PNG_TOK:
pNewHeightField->setHeightFieldType( PMHeightField::HFpng );
nextToken( );
break;
case PGM_TOK:
pNewHeightField->setHeightFieldType( PMHeightField::HFpgm );
nextToken( );
break;
case PPM_TOK:
pNewHeightField->setHeightFieldType( PMHeightField::HFppm );
nextToken( );
break;
case SYS_TOK:
pNewHeightField->setHeightFieldType( PMHeightField::HFsys );
nextToken( );
break;
default:
printExpected( i18n( "height field type" ), m_pScanner->sValue( ) );
return false;
}
if( m_token != STRING_TOK )
{
printExpected( i18n( "height field file" ), m_pScanner->sValue( ) );
return false;
}
else
{
pNewHeightField->setFileName( m_pScanner->sValue( ) );
nextToken( );
}
do
{
oldConsumed = m_consumedTokens;
switch( m_token )
{
case SMOOTH_TOK:
nextToken( );
pNewHeightField->setSmooth( true );
if( isTrue( ) )
nextToken( );
else if( isFalse( ) )
{
nextToken( );
pNewHeightField->setSmooth( false );
}
break;
case HIERARCHY_TOK:
pNewHeightField->setHierarchy( true );
nextToken( );
if( isTrue( ) )
nextToken( );
else if( isFalse( ) )
{
nextToken( );
pNewHeightField->setHierarchy( false );
}
break;
case WATER_LEVEL_TOK:
nextToken( );
if( parseFloat( wl ) )
{
if( ( wl < 0.0 ) || ( wl > 1.0 ) )
printError( i18n( "The water level has to be between 0 and 1" ) );
else
pNewHeightField->setWaterLevel( wl );
}
break;
}
parseChildObjects( pNewHeightField );
parseObjectModifiers( pNewHeightField );
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseText( PMText* pNewText )
{
int oldConsumed;
double thickness;
PMVector offset;
if( !parseToken( TEXT_TOK, "text" ) )
return false;
if( !parseToken( '{' ) )
return false;
if( !parseToken( TTF_TOK, "ttf" ) )
return false;
if( m_token != STRING_TOK )
{
printExpected( i18n( "font file name" ), m_pScanner->sValue( ) );
return false;
}
else
{
pNewText->setFont( m_pScanner->sValue( ) );
nextToken( );
}
if( m_token != STRING_TOK )
{
printExpected( i18n( "string of text" ), m_pScanner->sValue( ) );
return false;
}
else
{
pNewText->setText( m_pScanner->sValue( ) );
nextToken( );
}
if( !parseFloat( thickness ) )
return false;
pNewText->setThickness( thickness );
parseToken( ',' );
if( parseVector( offset, 2 ) )
pNewText->setOffset( offset );
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( pNewText );
parseObjectModifiers( pNewText );
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseJuliaFractal( PMJuliaFractal* pNewFractal )
{
int oldConsumed;
double d;
int i;
PMVector v( 4 ), v2( 2 );
if( !parseToken( JULIA_FRACTAL_TOK, "julia_fractal" ) )
return false;
if( !parseToken( '{' ) )
return false;
if( !parseVector( v, 4 ) )
return false;
pNewFractal->setJuliaParameter( v );
do
{
oldConsumed = m_consumedTokens;
switch( m_token )
{
case QUATERNION_TOK:
pNewFractal->setAlgebraType( PMJuliaFractal::Quaternion );
nextToken( );
break;
case HYPERCOMPLEX_TOK:
pNewFractal->setAlgebraType( PMJuliaFractal::Hypercomplex );
nextToken( );
break;
case STQR_TOK:
pNewFractal->setFunctionType( PMJuliaFractal::FTsqr );
nextToken( );
break;
case CUBE_TOK:
pNewFractal->setFunctionType( PMJuliaFractal::FTcube );
nextToken( );
break;
case EXP_TOK:
pNewFractal->setFunctionType( PMJuliaFractal::FTexp );
nextToken( );
break;
case RECIPROCAL_TOK:
pNewFractal->setFunctionType( PMJuliaFractal::FTreciprocal );
nextToken( );
break;
case SIN_TOK:
pNewFractal->setFunctionType( PMJuliaFractal::FTsin );
nextToken( );
break;
case ASIN_TOK:
pNewFractal->setFunctionType( PMJuliaFractal::FTasin );
nextToken( );
break;
case SINH_TOK:
pNewFractal->setFunctionType( PMJuliaFractal::FTsinh );
nextToken( );
break;
case ASINH_TOK:
pNewFractal->setFunctionType( PMJuliaFractal::FTasinh );
nextToken( );
break;
case COS_TOK:
pNewFractal->setFunctionType( PMJuliaFractal::FTcos );
nextToken( );
break;
case ACOS_TOK:
pNewFractal->setFunctionType( PMJuliaFractal::FTacos );
nextToken( );
break;
case COSH_TOK:
pNewFractal->setFunctionType( PMJuliaFractal::FTcosh );
nextToken( );
break;
case ACOSH_TOK:
pNewFractal->setFunctionType( PMJuliaFractal::FTacosh );
nextToken( );
break;
case TAN_TOK:
pNewFractal->setFunctionType( PMJuliaFractal::FTtan );
nextToken( );
break;
case ATAN_TOK:
pNewFractal->setFunctionType( PMJuliaFractal::FTatan );
nextToken( );
break;
case TANH_TOK:
pNewFractal->setFunctionType( PMJuliaFractal::FTtanh );
nextToken( );
break;
case ATANH_TOK:
pNewFractal->setFunctionType( PMJuliaFractal::FTatanh );
nextToken( );
break;
case LOG_TOK:
pNewFractal->setFunctionType( PMJuliaFractal::FTlog );
nextToken( );
break;
case PWR_TOK:
pNewFractal->setFunctionType( PMJuliaFractal::FTpwr );
nextToken( );
if( !parseToken( '(' ) )
return false;
if( !parseFloat( v2[0] ) )
return false;
parseToken( ',' );
if( !parseFloat( v2[1] ) )
return false;
if( !parseToken( ')' ) )
return false;
pNewFractal->setExponent( v2 );
break;
case MAX_ITERATION_TOK:
nextToken( );
if( !parseInt( i ) )
return false;
if( i <= 0 )
{
printWarning( i18n( "Maximum iterations are less than 1, fixed" ) );
i = 1;
}
pNewFractal->setMaximumIterations( i );
break;
case PRECISION_TOK:
nextToken( );
if( !parseFloat( d ) )
return false;
if( d < 1.0 )
{
printWarning( i18n( "Precision is less than 1.0, fixed" ) );
d = 1.0;
}
pNewFractal->setPrecision( d );
break;
case SLICE_TOK:
nextToken( );
if( !parseVector( v, 4 ) )
return false;
pNewFractal->setSliceNormal( v );
parseToken( ',' );
if( !parseFloat( d ) )
return false;
pNewFractal->setSliceDistance( d );
break;
}
parseChildObjects( pNewFractal );
parseObjectModifiers( pNewFractal );
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parsePlane( PMPlane* pNewPlane )
{
double dist;
PMVector vector;
int oldConsumed;
if( !parseToken( PLANE_TOK, "plane" ) )
return false;
if( !parseToken( '{' ) )
return false;
if( !parseVector( vector ) )
return false;
pNewPlane->setNormal( vector );
if( !parseToken( ',' ) )
return false;
if( !parseFloat( dist ) )
return false;
pNewPlane->setDistance( dist );
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( pNewPlane );
parseObjectModifiers( pNewPlane );
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
const int c_polynomSize[8] = { 0, 0, 10, 20, 35, 56, 84, 120 };
bool PMPovrayParser::parsePolynom( PMPolynom* pNewPoly )
{
PMVector vector;
double d;
PMVector c;
int oldConsumed;
int order = 2;
int type = m_token;
pNewPoly->setSturm( false );
if( ( m_token == QUADRIC_TOK ) || ( m_token == CUBIC_TOK ) ||
( m_token == QUARTIC_TOK ) || ( m_token == POLY_TOK ) )
{
nextToken( );
if( !parseToken( '{' ) )
return false;
}
else
printExpected( "poly", m_pScanner->sValue( ) );
if( type == QUADRIC_TOK )
{
c = PMVector( 10 );
pNewPoly->setPolynomOrder( 2 );
// parse the quadric coefficients
if( !parseVectorLiteral( vector ) )
return false;
vector.resize( 3 );
c[0] = vector[0];
c[4] = vector[1];
c[7] = vector[2];
parseToken( ',' );
if( !parseVectorLiteral( vector ) )
return false;
vector.resize( 3 );
c[1] = vector[0];
c[2] = vector[1];
c[5] = vector[2];
parseToken( ',' );
if( !parseVectorLiteral( vector ) )
return false;
vector.resize( 3 );
c[3] = vector[0];
c[6] = vector[1];
c[8] = vector[2];
parseToken( ',' );
if( !parseFloat( d ) )
return false;
c[9] = d;
pNewPoly->setCoefficients( c );
}
else
{
if( type == CUBIC_TOK )
order = 3;
else if( type == QUARTIC_TOK )
order = 4;
else
{
if( !parseInt( order ) )
return false;
if( ( order < 2 ) || ( order > 7 ) )
{
printError( i18n( "The polynom order has to be between 2 and 7 inclusive" ) );
return false;
}
parseToken( ',' );
}
pNewPoly->setPolynomOrder( order );
if( !parseVectorLiteral( vector ) )
return false;
if( vector.size( ) != ( unsigned ) c_polynomSize[order] )
{
printError( i18n( "%1 coefficients are needed for a polynom with order %2" )
.arg( c_polynomSize[order] ).arg( order ) );
vector.resize( c_polynomSize[order] );
}
pNewPoly->setCoefficients( vector );
}
do
{
oldConsumed = m_consumedTokens;
if( m_token == STURM_TOK )
{
pNewPoly->setSturm( true );
nextToken( );
}
parseChildObjects( pNewPoly );
parseObjectModifiers( pNewPoly );
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseBicubicPatch( PMBicubicPatch* pNewPatch )
{
PMVector vector;
bool stop = false;
int oldConsumed;
int type;
int steps;
double flatness;
int i;
if( !parseToken( BICUBIC_PATCH_TOK, "bicubic_patch" ) )
return false;
if( !parseToken( '{' ) )
return false;
// parse patch items
do
{
switch( m_token )
{
case TYPE_TOK:
nextToken( );
if( parseInt( type ) )
{
if( ( type == 0 ) || ( type == 1 ) )
pNewPatch->setPatchType( type );
else
printError( i18n( "Patch type has to be 0 or 1" ) );
}
break;
case U_STEPS_TOK:
nextToken( );
if( parseInt( steps ) )
pNewPatch->setUSteps( steps );
break;
case V_STEPS_TOK:
nextToken( );
if( parseInt( steps ) )
pNewPatch->setVSteps( steps );
break;
case FLATNESS_TOK:
nextToken( );
if( parseFloat( flatness ) )
pNewPatch->setFlatness( flatness );
break;
case UV_VECTORS_TOK:
pNewPatch->enableUV( true );
nextToken( );
for ( i = 0; i < 4; ++i )
{
if( parseVector( vector ) )
pNewPatch->setUVVector( i, vector );
else
return false;
}
break;
case ',':
nextToken( );
stop = true;
break;
default:
stop = true;
break;
}
}
while( !stop );
// parse control points
stop = false;
for( i = 0; ( i < 16 ) && !stop; i++ )
{
if( parseVector( vector ) )
{
pNewPatch->setControlPoint( i, vector );
if( i < 15 )
if( !parseToken( ',' ) )
stop = true;
}
else
stop = true;
}
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( pNewPatch );
parseObjectModifiers( pNewPatch );
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseDisc( PMDisc* pNewDisc )
{
double d;
PMVector vector;
int oldConsumed;
if( !parseToken( DISC_TOK, "disc" ) )
return false;
if( !parseToken( '{' ) )
return false;
if( !parseVector( vector ) )
return false;
pNewDisc->setCenter( vector );
if( !parseToken( ',' ) )
return false;
if( !parseVector( vector ) )
return false;
pNewDisc->setNormal( vector );
if( !parseToken( ',' ) )
return false;
if( !parseFloat( d ) )
return false;
pNewDisc->setRadius( d );
if( m_token == ',' )
{
nextToken( );
if( !parseFloat( d ) )
return false;
pNewDisc->setHoleRadius( d );
}
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( pNewDisc );
parseObjectModifiers( pNewDisc );
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseTriangle( PMTriangle* pNewTriangle )
{
PMVector vector;
int oldConsumed;
int i;
if( m_token == SMOOTH_TRIANGLE_TOK )
pNewTriangle->setSmoothTriangle( true );
else if( m_token == TRIANGLE_TOK )
pNewTriangle->setSmoothTriangle( false );
else
{
printExpected( "triangle", m_pScanner->sValue( ) );
return false;
}
nextToken( );
if( !parseToken( '{' ) )
return false;
for( i = 0; i < 3; i++ )
{
if( i != 0 )
parseToken( ',' );
if( !parseVector( vector ) )
return false;
pNewTriangle->setPoint( i, vector );
if( pNewTriangle->isSmoothTriangle( ) )
{
parseToken( ',' );
if( !parseVector( vector ) )
return false;
pNewTriangle->setNormal( i, vector );
}
}
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( pNewTriangle );
parseObjectModifiers( pNewTriangle );
if( m_token == UV_VECTORS_TOK )
{
nextToken( );
pNewTriangle->enableUV( true );
for ( i = 0; i < 3; ++i )
{
if( parseVector( vector ) )
pNewTriangle->setUVVector( i, vector );
else
return false;
}
}
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseLathe( PMLathe* pNewLathe )
{
PMVector vector;
int oldConsumed;
int i;
bool stop = false;
if( !parseToken( LATHE_TOK, "lathe" ) )
return false;
if( !parseToken( '{' ) )
return false;
int minp = 2;
while( !stop )
{
switch( m_token )
{
case LINEAR_SPLINE_TOK:
pNewLathe->setSplineType( PMLathe::LinearSpline );
nextToken( );
minp = 2;
break;
case QUADRATIC_SPLINE_TOK:
pNewLathe->setSplineType( PMLathe::QuadraticSpline );
nextToken( );
minp = 3;
break;
case CUBIC_SPLINE_TOK:
pNewLathe->setSplineType( PMLathe::CubicSpline );
nextToken( );
minp = 4;
break;
case BEZIER_SPLINE_TOK:
pNewLathe->setSplineType( PMLathe::BezierSpline );
nextToken( );
minp = 4;
break;
default:
stop = true;
break;
}
}
int nump;
if( !parseInt( nump ) )
return false;
TQValueList<PMVector> points;
for( i = 0; i < nump; i++ )
{
parseToken( ',' );
if( !parseVector( vector ) )
return false;
vector.resize( 2 );
points.append( vector );
}
if( nump < minp )
printError( i18n( "At least %1 points are needed for that spline type" )
.arg( minp ) );
else if( ( pNewLathe->splineType( ) == PMLathe::BezierSpline ) &&
( ( nump % 4 ) != 0 ) )
printError( i18n( "Bezier splines need 4 points for each segment" ) );
else
pNewLathe->setPoints( points );
do
{
oldConsumed = m_consumedTokens;
if( m_token == STURM_TOK )
{
pNewLathe->setSturm( true );
nextToken( );
}
parseChildObjects( pNewLathe );
parseObjectModifiers( pNewLathe );
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parsePrism( PMPrism* pNewPrism )
{
PMVector vector;
double height;
int oldConsumed;
int i;
bool stop = false;
if( !parseToken( PRISM_TOK, "prism" ) )
return false;
if( !parseToken( '{' ) )
return false;
int minp = 3;
while( !stop )
{
switch( m_token )
{
case LINEAR_SPLINE_TOK:
pNewPrism->setSplineType( PMPrism::LinearSpline );
nextToken( );
minp = 3;
break;
case QUADRATIC_SPLINE_TOK:
pNewPrism->setSplineType( PMPrism::QuadraticSpline );
nextToken( );
minp = 4;
break;
case CUBIC_SPLINE_TOK:
pNewPrism->setSplineType( PMPrism::CubicSpline );
nextToken( );
minp = 5;
break;
case BEZIER_SPLINE_TOK:
pNewPrism->setSplineType( PMPrism::BezierSpline );
nextToken( );
minp = 4;
break;
case LINEAR_SWEEP_TOK:
pNewPrism->setSweepType( PMPrism::LinearSweep );
nextToken( );
break;
case CONIC_SWEEP_TOK:
pNewPrism->setSweepType( PMPrism::ConicSweep );
nextToken( );
break;
default:
stop = true;
break;
}
}
if( !parseFloat( height ) )
return false;
pNewPrism->setHeight1( height );
parseToken( ',' );
if( !parseFloat( height ) )
return false;
pNewPrism->setHeight2( height );
parseToken( ',' );
int nump;
if( !parseInt( nump ) )
return false;
TQValueList<PMVector> allPoints;
for( i = 0; i < nump; i++ )
{
parseToken( ',' );
if( !parseVector( vector ) )
return false;
vector.resize( 2 );
allPoints.append( vector );
}
TQValueList< TQValueList<PMVector> > points;
TQValueList<PMVector> subPoints;
TQValueList<PMVector>::Iterator it = allPoints.begin( );
int pnr = 0, pmod4;
PMVector ref( 2 ), ref2( 2 );
bool error = false;
bool last = false;
switch( pNewPrism->splineType( ) )
{
case PMPrism::LinearSpline:
for( ; ( it != allPoints.end( ) ) && !error; ++it, pnr++ )
{
if( pnr == 0 )
{
ref = *it;
subPoints.append( *it );
}
else
{
if( ref.approxEqual( *it ) )
{
if( pnr < 3 )
{
printError( i18n( "Linear splines need at least 4 points." ) );
error = true;
}
else
{
points.append( subPoints );
subPoints.clear( );
pnr = -1;
}
}
else
subPoints.append( *it );
}
}
if( ( pnr != 0 ) && ( !error ) )
{
printWarning( i18n( "Linear spline not closed" ) );
if( pnr < 3 )
{
printError( i18n( "Linear splines need at least 4 points." ) );
error = true;
}
else
{
points.append( subPoints );
subPoints.clear( );
}
}
break;
case PMPrism::QuadraticSpline:
for( ; ( it != allPoints.end( ) ) && !error; ++it, pnr++ )
{
if( pnr == 0 )
subPoints.append( *it );
else if( pnr == 1 )
{
ref = *it;
subPoints.append( *it );
}
else
{
if( ref.approxEqual( *it ) )
{
if( pnr < 4 )
{
printError( i18n( "Quadratic splines need at least 5 points." ) );
error = true;
}
else
{
points.append( subPoints );
subPoints.clear( );
pnr = -1;
}
}
else
subPoints.append( *it );
}
}
if( ( pnr != 0 ) && ( !error ) )
{
printError( i18n( "Quadratic spline not closed" ) );
error = true;
}
break;
case PMPrism::CubicSpline:
for( ; ( it != allPoints.end( ) ) && !error; ++it, pnr++ )
{
if( pnr == 0 )
subPoints.append( *it );
else if( pnr == 1 )
{
ref = *it;
subPoints.append( *it );
}
else if( last )
{
if( pnr < 5 )
{
printError( i18n( "Cubic splines need at least 6 points." ) );
error = true;
}
else
{
subPoints.append( *it );
points.append( subPoints );
subPoints.clear( );
pnr = -1;
last = false;
}
}
else
{
if( ref.approxEqual( *it ) )
last = true;
else
subPoints.append( *it );
}
}
if( ( pnr != 0 ) && ( !error ) )
{
printError( i18n( "Cubic spline not closed" ) );
error = true;
}
break;
case PMPrism::BezierSpline:
for( ; ( it != allPoints.end( ) ) && !error; ++it, pnr++ )
{
pmod4 = pnr % 4;
if( pnr == 0 )
{
ref = *it;
subPoints.append( *it );
}
else if( pmod4 == 0 )
{
if( !ref2.approxEqual( *it ) )
{
printError( i18n( "Bezier spline not closed" ) );
error = true;
}
}
else if( pmod4 == 3 )
{
if( ref.approxEqual( *it ) )
{
points.append( subPoints );
subPoints.clear( );
pnr = -1;
}
else
{
subPoints.append( *it );
ref2 = *it;
}
}
else
subPoints.append( *it );
}
if( ( pnr != 0 ) && ( !error ) )
{
printError( i18n( "Bezier spline not closed" ) );
error = true;
}
break;
}
if( !error )
pNewPrism->setPoints( points );
do
{
oldConsumed = m_consumedTokens;
switch( m_token )
{
case STURM_TOK:
pNewPrism->setSturm( true );
nextToken( );
break;
case OPEN_TOK:
pNewPrism->setOpen( true );
nextToken( );
break;
default:
break;
}
parseChildObjects( pNewPrism );
parseObjectModifiers( pNewPrism );
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseSor( PMSurfaceOfRevolution* pNewSor )
{
PMVector vector;
int oldConsumed;
int i;
if( !parseToken( SOR_TOK, "sor" ) )
return false;
if( !parseToken( '{' ) )
return false;
int nump;
if( !parseInt( nump ) )
return false;
TQValueList<PMVector> points;
for( i = 0; i < nump; i++ )
{
parseToken( ',' );
if( !parseVector( vector ) )
return false;
vector.resize( 2 );
points.append( vector );
}
if( nump < 4 )
printError( i18n( "At least 4 points are needed for the surface of revolution" ) );
else
{
TQValueList<PMVector>::Iterator it1 = points.begin( );
TQValueList<PMVector>::Iterator it2 = it1; ++it2;
TQValueList<PMVector>::Iterator it3 = it2; ++it3;
int pnr = 0;
for( ; it3 != points.end( ); ++it1, ++it2, ++it3, pnr++ )
{
if( ( pnr == 0 ) || ( pnr == ( nump - 3 ) ) )
{
if( approxZero( ( *it1 )[1] - ( *it3 )[1], c_sorTolerance ) )
{
printError( i18n( "The v coordinate of point %1 and %2 must be different; fixed" )
.arg( pnr + 1 ).arg( pnr + 3 ) );
if( pnr == 0 )
( *it1 )[1] = ( *it3 )[1] - c_sorTolerance;
else
( *it3 )[1] = ( *it1 )[1] + c_sorTolerance;
}
}
if( pnr != 0 )
{
if( ( ( *it2 )[1] - ( *it1 )[1] ) < c_sorTolerance )
{
printError( i18n( "The v coordinates must be strictly increasing; fixed" ) );
( *it2 )[1] = ( *it1 )[1] + c_sorTolerance;
}
}
}
pNewSor->setPoints( points );
}
do
{
oldConsumed = m_consumedTokens;
switch( m_token )
{
case STURM_TOK:
pNewSor->setSturm( true );
nextToken( );
break;
case OPEN_TOK:
pNewSor->setOpen( true );
nextToken( );
break;
default:
break;
}
parseChildObjects( pNewSor );
parseObjectModifiers( pNewSor );
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseSqe( PMSuperquadricEllipsoid* pNewSqe )
{
PMVector vector;
int oldConsumed;
if( !parseToken( SUPERELLIPSOID_TOK ) )
return false;
if( !parseToken( '{' ) )
return false;
if( !parseVector( vector ) )
return false;
vector.resize( 2 );
if( vector[0] < 0.001 )
{
printError( i18n( "The east-west exponent must be greater than 0.001" ) );
vector[0] = 0.001;
}
if( vector[1] < 0.001 )
{
printError( i18n( "The north-south exponent must be greater than 0.001" ) );
vector[1] = 0.001;
}
pNewSqe->setEastWestExponent( vector[0] );
pNewSqe->setNorthSouthExponent( vector[1] );
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( pNewSqe );
parseObjectModifiers( pNewSqe );
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseRotate( PMRotate* rotate )
{
PMVector v;
if( !parseToken( ROTATE_TOK, "rotate" ) )
return false;
if( !parseVector( v ) )
return false;
rotate->setRotation( v );
return true;
}
bool PMPovrayParser::parseScale( PMScale* scale )
{
PMVector v;
if( !parseToken( SCALE_TOK, "scale" ) )
return false;
if( !parseVector( v ) )
return false;
scale->setScale( v );
return true;
}
bool PMPovrayParser::parseTranslate( PMTranslate* translate )
{
PMVector v;
if( !parseToken( TRANSLATE_TOK, "translate" ) )
return false;
if( !parseVector( v ) )
return false;
translate->setTranslation( v );
return true;
}
bool PMPovrayParser::parseMatrix( PMPovrayMatrix* matrix )
{
PMVector v;
if( !parseToken( MATRIX_TOK ), "matrix" )
return false;
if( !parseVectorLiteral( v ) )
return false;
if( v.size( ) != 12 )
{
printError( i18n( "Wrong number of matrix values." ) );
v.resize( 12 );
}
matrix->setValues( v );
return true;
}
bool PMPovrayParser::parseBoundedBy( PMBoundedBy* bound )
{
int oldConsumed;
if( !parseToken( BOUNDED_BY_TOK, "bounded_by" ) )
return false;
if( !parseToken( '{' ) )
return false;
do
{
oldConsumed = m_consumedTokens;
if( m_token == CLIPPED_BY_TOK )
nextToken( );
parseChildObjects( bound );
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseClippedBy( PMClippedBy* clipped )
{
int oldConsumed;
if( !parseToken( CLIPPED_BY_TOK, "clipped_by" ) )
return false;
if( !parseToken( '{' ) )
return false;
do
{
oldConsumed = m_consumedTokens;
if( m_token == BOUNDED_BY_TOK )
nextToken( );
parseChildObjects( clipped );
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseCamera( PMCamera* camera )
{
PMVector v;
double d;
int i;
int oldConsumed;
if( !parseToken( CAMERA_TOK, "camera" ) )
return false;
if( !parseToken( '{' ) )
return false;
do
{
oldConsumed = m_consumedTokens;
do
{
oldConsumed = m_consumedTokens;
switch( m_token )
{
case PERSPECTIVE_TOK:
nextToken( );
camera->setCameraType( PMCamera::Perspective );
break;
case ORTHOGRAPHIC_TOK:
nextToken( );
camera->setCameraType( PMCamera::Orthographic );
break;
case FISHEYE_TOK:
nextToken( );
camera->setCameraType( PMCamera::FishEye );
break;
case ULTRA_WIDE_ANGLE_TOK:
nextToken( );
camera->setCameraType( PMCamera::UltraWideAngle );
break;
case OMNIMAX_TOK:
nextToken( );
camera->setCameraType( PMCamera::Omnimax );
break;
case PANORAMIC_TOK:
nextToken( );
camera->setCameraType( PMCamera::Panoramic );
break;
case CYLINDER_TOK:
nextToken( );
camera->setCameraType( PMCamera::Cylinder );
if( parseInt( i ) )
camera->setCylinderType( i );
break;
case LOCATION_TOK:
nextToken( );
if( parseVector( v ) )
camera->setLocation( v );
break;
case SKY_TOK:
nextToken( );
if( parseVector( v ) )
camera->setSky( v );
break;
case UP_TOK:
nextToken( );
if( parseVector( v ) )
camera->setUp( v );
break;
case RIGHT_TOK:
nextToken( );
if( parseVector( v ) )
camera->setRight( v );
break;
case DIRECTION_TOK:
nextToken( );
if( parseVector( v ) )
camera->setDirection( v );
break;
case LOOK_AT_TOK:
nextToken( );
if( parseVector( v ) )
camera->setLookAt( v );
break;
case ANGLE_TOK:
nextToken( );
if( parseFloat( d ) )
{
camera->enableAngle( true );
camera->setAngle( d );
}
break;
case BLUR_SAMPLES_TOK:
nextToken( );
camera->enableFocalBlur( true );
if( parseInt( i ) )
camera->setBlurSamples( i );
break;
case APERTURE_TOK:
nextToken( );
camera->enableFocalBlur( true );
if( parseFloat( d ) )
camera->setAperture( d );
break;
case FOCAL_POINT_TOK:
nextToken( );
if( parseVector( v ) )
camera->setFocalPoint( v );
break;
case CONFIDENCE_TOK:
nextToken( );
if( parseFloat( d ) )
camera->setConfidence( d );
break;
case VARIANCE_TOK:
nextToken( );
if( parseFloat( d ) )
camera->setVariance( d );
break;
default:
break;
}
}
while( oldConsumed != m_consumedTokens );
parseChildObjects( camera );
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseLight( PMLight* light )
{
PMVector v;
PMColor c;
double d;
int i;
int oldConsumed;
if( !parseToken( LIGHT_SOURCE_TOK, "light_source" ) )
return false;
if( !parseToken( '{' ) )
return false;
if( !parseVector( v ) )
return false;
light->setLocation( v );
if( m_token == ',' )
nextToken( );
if( !parseColor( c ) )
return false;
light->setColor( c );
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( light );
switch( m_token )
{
case SPOTLIGHT_TOK:
nextToken( );
light->setLightType( PMLight::SpotLight );
break;
case CYLINDER_TOK:
nextToken( );
light->setLightType( PMLight::CylinderLight );
break;
case SHADOWLESS_TOK:
nextToken( );
light->setLightType( PMLight::ShadowlessLight );
break;
case RADIUS_TOK:
nextToken( );
if( parseFloat( d ) )
light->setRadius( d );
break;
case FALLOFF_TOK:
nextToken( );
if( parseFloat( d ) )
light->setFalloff( d );
break;
case TIGHTNESS_TOK:
nextToken( );
if( parseFloat( d ) )
light->setTightness( d );
break;
case POINT_AT_TOK:
nextToken( );
if( parseVector( v ) )
light->setPointAt( v );
break;
case PARALLEL_TOK:
nextToken( );
light->setParallel( parseBool( ) );
break;
case AREA_LIGHT_TOK:
nextToken( );
light->setAreaLight( true );
if( parseVector( v ) )
light->setAxis1( v );
parseToken( ',' );
if( parseVector( v ) )
light->setAxis2( v );
parseToken( ',' );
if( parseInt( i ) )
light->setSize1( i );
parseToken( ',' );
if( parseInt( i ) )
light->setSize2( i );
break;
case AREA_CIRCULAR_TOK:
nextToken( );
light->setAreaType( PMLight::Circular );
break;
case ADAPTIVE_TOK:
nextToken( );
if( parseInt( i ) )
light->setAdaptive( i );
break;
case ORIENT_TOK:
nextToken( );
light->setOrient( parseBool( ) );
break;
case JITTER_TOK:
nextToken( );
light->setJitter( parseBool( ) );
break;
case FADE_POWER_TOK:
nextToken( );
light->setFading( true );
if( parseInt( i ) )
light->setFadePower( i );
break;
case FADE_DISTANCE_TOK:
nextToken( );
light->setFading( true );
if( parseFloat( d ) )
light->setFadeDistance( d );
break;
case MEDIA_INTERACTION_TOK:
nextToken( );
light->setMediaInteraction( parseBool( ) );
break;
case MEDIA_ATTENUATION_TOK:
nextToken( );
light->setMediaAttenuation( parseBool( ) );
break;
default:
break;
}
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseLooksLike( PMLooksLike* ll )
{
if( !parseToken( LOOKS_LIKE_TOK, "looks_like" ) )
return false;
if( !parseToken( '{' ) )
return false;
parseChildObjects( ll );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseProjectedThrough( PMProjectedThrough* ll )
{
if( !parseToken( PROJECTED_THROUGH_TOK, "projected_through" ) )
return false;
if( !parseToken( '{' ) )
return false;
parseChildObjects( ll );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseTexture( PMTexture* texture, bool parseOuter )
{
int oldConsumed;
if( parseOuter )
{
if( !parseToken( TEXTURE_TOK, "texture" ) )
return false;
if( !parseToken( '{' ) )
return false;
}
if( m_token == ID_TOK )
{
TQString id( m_pScanner->sValue( ) );
PMDeclare* decl = checkLink( id );
if( decl )
{
if( !texture->setLinkedObject( decl ) )
printError( i18n( "Wrong declare type" ) );
}
nextToken( );
}
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( texture );
if( m_token == UV_MAPPING_TOK )
{
nextToken();
texture->setUVMapping( parseBool( ) );
}
}
while( oldConsumed != m_consumedTokens );
if( parseOuter )
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parsePattern( PMPattern* pattern, bool normal )
{
PMVector vector;
double f_number;
int i_number;
int oldConsumed;
bool type;
do
{
oldConsumed = m_consumedTokens;
type = false;
switch( m_token )
{
case AGATE_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternAgate );
type = true;
break;
case AGATE_TURB_TOK:
nextToken( );
if( !parseFloat( f_number ) )
return false;
pattern->setAgateTurbulence( f_number );
break;
case AVERAGE_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternAverage );
type = true;
break;
case BOXED_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternBoxed );
type = true;
break;
case BOZO_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternBozo );
type = true;
break;
case BUMPS_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternBumps );
type = true;
break;
case CELLS_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternCells );
type = true;
break;
case CRACKLE_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternCrackle );
type = true;
break;
case CYLINDRICAL_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternCylindrical );
type = true;
break;
case DENTS_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternDents );
type = true;
break;
case DENSITY_FILE_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternDensity );
type = true;
if( !parseToken( DF3_TOK, "df3" ) )
return false;
if( m_token != STRING_TOK )
{
printError( i18n( "Expecting a file name." ) );
return false;
}
else
{
pattern->setDensityFile( m_pScanner->sValue( ) );
nextToken( );
}
if( parseToken( INTERPOLATE_TOK, "interpolate" ) )
{
if( !parseInt( i_number ) )
return false;
else
pattern->setDensityInterpolate( i_number );
}
break;
case GRADIENT_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternGradient );
type = true;
if( !parseVector( vector ) )
return false;
pattern->setGradient( vector );
break;
case GRANITE_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternGranite );
type = true;
break;
case JULIA_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternJulia );
type = true;
if( !parseVector( vector ) )
return false;
pattern->setJuliaComplex( vector );
if( !parseInt( i_number ) )
return false;
pattern->setMaxIterations( i_number );
break;
case LEOPARD_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternLeopard );
type = true;
break;
case MANDEL_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternMandel );
type = true;
if( !parseInt( i_number ) )
return false;
pattern->setMaxIterations( i_number );
break;
case MARBLE_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternMarble );
type = true;
break;
case ONION_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternOnion );
type = true;
break;
case PLANAR_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternPlanar );
type = true;
break;
case QUILTED_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternQuilted );
type = true;
break;
case CONTROL0_TOK:
nextToken( );
if( !parseFloat( f_number ) )
return false;
pattern->setQuiltControl0( f_number );
break;
case CONTROL1_TOK:
nextToken( );
if( !parseFloat( f_number ) )
return false;
pattern->setQuiltControl1( f_number );
break;
case RADIAL_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternRadial );
type = true;
break;
case RIPPLES_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternRipples );
type = true;
break;
case SLOPE_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternSlope );
type = true;
if( !parseToken( '{' ) )
return false;
if( !parseVector( vector ) )
return false;
pattern->setSlopeDirection( vector );
if ( parseToken( ',' ) )
{
if( !parseFloat( f_number ) )
return false;
pattern->setSlopeLoSlope( f_number );
if ( parseToken( ',' ) )
{
if ( !parseFloat( f_number ) )
return false;
pattern->setSlopeHiSlope( f_number );
}
}
if( m_token == ALTITUDE_TOK )
{
pattern->setSlopeAltFlag( true );
nextToken( );
if ( !parseVector( vector ) )
return false;
pattern->setSlopeAltitude( vector );
if( parseToken( ',' ) )
{
if ( !parseFloat( f_number ) )
return false;
pattern->setSlopeLoAlt( f_number );
if ( parseToken( ',' ) )
{
if( !parseFloat( f_number ) )
return false;
pattern->setSlopeHiAlt( f_number );
}
}
}
if( !parseToken( '}' ) )
return false;
break;
case SPHERICAL_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternSpherical );
type = true;
break;
case SPIRAL1_TOK:
case SPIRAL2_TOK:
if( m_token == SPIRAL1_TOK )
pattern->setPatternType( PMPattern::PatternSpiral1 );
else
pattern->setPatternType( PMPattern::PatternSpiral2 );
type = true;
nextToken( );
if( !parseInt( i_number ) )
return false;
pattern->setSpiralNumberArms( i_number );
break;
case SPOTTED_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternSpotted );
type = true;
break;
case WAVES_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternWaves );
type = true;
break;
case WOOD_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternWood );
type = true;
break;
case WRINKLES_TOK:
nextToken( );
pattern->setPatternType( PMPattern::PatternWrinkles );
type = true;
break;
//crackle parameters
case FORM_TOK:
nextToken( );
if( !parseVector( vector ) )
return false;
pattern->setCrackleForm( vector );
break;
case METRIC_TOK:
nextToken( );
if ( !parseInt( i_number ) )
return false;
pattern->setCrackleMetric( i_number );
break;
case OFFSET_TOK:
nextToken( );
if( !parseFloat( f_number ) )
return false;
pattern->setCrackleOffset( f_number );
break;
case SOLID_TOK:
nextToken( );
pattern->setCrackleSolid( true );
break;
//fractal parameters
case MAGNET_TOK:
nextToken( );
pattern->setFractalMagnet( true );
if ( !parseInt( i_number ) )
return false;
pattern->setFractalMagnetType( i_number );
break;
case EXPONENT_TOK:
nextToken( );
if ( !parseInt( i_number ) )
return false;
pattern->setFractalExponent( i_number );
break;
case EXTERIOR_TOK:
nextToken( );
if ( !parseInt( i_number ) )
return false;
pattern->setFractalExtType( i_number );
if ( !parseFloat( f_number ) )
return false;
pattern->setFractalExtFactor( f_number );
break;
case INTERIOR_TOK:
nextToken( );
if ( !parseInt( i_number ) )
return false;
pattern->setFractalIntType( i_number );
if ( !parseFloat( f_number ) )
return false;
pattern->setFractalIntFactor( f_number );
break;
//turbulence
case TURBULENCE_TOK:
nextToken( );
pattern->enableTurbulence( true );
if( !parseVector( vector ) )
return false;
pattern->setValueVector( vector );
break;
case OCTAVES_TOK:
nextToken( );
if( !parseInt( i_number ) )
return false;
pattern->setOctaves( i_number );
break;
case OMEGA_TOK:
nextToken( );
if( !parseFloat( f_number ) )
return false;
pattern->setOmega( f_number );
break;
case LAMBDA_TOK:
nextToken( );
if( !parseFloat( f_number ) )
return false;
pattern->setLambda( f_number );
break;
case NOISE_GENERATOR_TOK:
nextToken( );
if( !parseInt( i_number ) )
return false;
pattern->setNoiseGenerator( ( PMPattern::PMNoiseType ) ( i_number ) );
break;
default:
break;
}
if( type && normal )
{
// try to parse the normal pattern depth
double depth;
if( parseFloat( depth, true ) )
pattern->setDepth( depth );
}
}
while( oldConsumed != m_consumedTokens );
return true;
}
bool PMPovrayParser::parseBlendMapModifiers( PMBlendMapModifiers* blend )
{
int oldConsumed;
double f_number;
do
{
oldConsumed = m_consumedTokens;
switch( m_token )
{
case FREQUENCY_TOK:
nextToken( );
if( !parseFloat( f_number ) )
return false;
blend->enableFrequency( true );
blend->setFrequency( f_number );
break;
case PHASE_TOK:
nextToken( );
if( !parseFloat( f_number ) )
return false;
blend->enablePhase( true );
blend->setPhase( f_number );
break;
case RAMP_WAVE_TOK:
nextToken( );
blend->enableWaveForm( true );
blend->setWaveFormType( PMBlendMapModifiers::RampWave );
break;
case TRIANGLE_WAVE_TOK:
nextToken( );
blend->enableWaveForm( true );
blend->setWaveFormType( PMBlendMapModifiers::TriangleWave );
break;
case SINE_WAVE_TOK:
nextToken( );
blend->enableWaveForm( true );
blend->setWaveFormType( PMBlendMapModifiers::SineWave );
break;
case SCALLOP_WAVE_TOK:
nextToken( );
blend->enableWaveForm( true );
blend->setWaveFormType( PMBlendMapModifiers::ScallopWave );
break;
case CUBIC_WAVE_TOK:
nextToken( );
blend->enableWaveForm( true );
blend->setWaveFormType( PMBlendMapModifiers::CubicWave );
break;
case POLY_WAVE_TOK:
nextToken( );
blend->enableWaveForm( true );
blend->setWaveFormType( PMBlendMapModifiers::PolyWave );
if( parseFloat( f_number, true ) )
blend->setWaveFormExponent( f_number );
break;
}
}
while( oldConsumed != m_consumedTokens );
return true;
}
bool PMPovrayParser::parseWarp( PMWarp* warp )
{
int oldConsumed;
PMVector vector;
double f_number;
int i_number;
bool parsedFirst;
bool mapping;
if( !parseToken( WARP_TOK, "warp" ) )
return false;
if( !parseToken( '{' ) )
return false;
mapping = false;
parsedFirst = false;
do
{
oldConsumed = m_consumedTokens;
if( !parsedFirst &&
( m_token != REPEAT_TOK ||
m_token != BLACK_HOLE_TOK ||
m_token != TURBULENCE_TOK ||
m_token != CYLINDRICAL_TOK ||
m_token != SPHERICAL_TOK ||
m_token != TOROIDAL_TOK ||
m_token != PLANAR_TOK ) )
{
printError( i18n( "Expecting a warp type" ) );
return false;
}
switch( m_token )
{
case REPEAT_TOK:
nextToken( );
if( !parsedFirst )
{
warp->setWarpType( PMWarp::Repeat );
if( !parseVector( vector ) )
return false;
warp->setDirection( vector );
parsedFirst = true;
}
else
{
if( !parseVector( vector ) )
return false;
warp->setRepeat( vector );
}
break;
case OFFSET_TOK:
nextToken( );
if( !parseVector( vector ) )
return false;
warp->setOffset( vector );
break;
case FLIP_TOK:
nextToken( );
if( !parseVector( vector ) )
return false;
warp->setFlip( vector );
break;
case BLACK_HOLE_TOK:
nextToken( );
warp->setWarpType( PMWarp::BlackHole );
if( !parseVector( vector ) )
return false;
warp->setLocation( vector );
if( !parseToken( ',' ) )
return false;
if( !parseFloat( f_number ) )
return false;
warp->setRadius( f_number );
parsedFirst = true;
break;
case STRENGTH_TOK:
nextToken( );
if( !parseFloat( f_number ) )
return false;
warp->setStrength( f_number );
break;
case FALLOFF_TOK:
nextToken( );
if( !parseFloat( f_number ) )
return false;
warp->setFalloff( f_number );
break;
case INVERSE_TOK:
nextToken( );
warp->setInverse( true );
break;
case TURBULENCE_TOK:
if( !parsedFirst )
{
nextToken( );
warp->setWarpType( PMWarp::Turbulence );
if( !parseVector( vector ) )
return false;
warp->setValueVector( vector );
parsedFirst = true;
}
else
{
if( !parseVector( vector ) )
return false;
warp->setTurbulence( vector );
}
break;
case OCTAVES_TOK:
nextToken( );
if( !parseInt( i_number ) )
return false;
warp->setOctaves( i_number );
break;
case OMEGA_TOK:
nextToken( );
if( !parseFloat( f_number ) )
return false;
warp->setOmega( f_number );
break;
case LAMBDA_TOK:
nextToken( );
if( !parseFloat( f_number ) )
return false;
warp->setLambda( f_number );
break;
case CYLINDRICAL_TOK:
warp->setWarpType( PMWarp::Cylindrical );
mapping = true;
break;
case SPHERICAL_TOK:
warp->setWarpType( PMWarp::Spherical );
mapping = true;
break;
case TOROIDAL_TOK:
warp->setWarpType( PMWarp::Toroidal );
mapping = true;
break;
case PLANAR_TOK:
nextToken( );
warp->setWarpType( PMWarp::Planar );
if( parseVector( vector ) )
{
warp->setOrientation( vector );
if( parseToken( ',' ) )
{
if( !parseFloat( f_number ) )
return false;
warp->setDistExp( f_number );
}
}
parsedFirst = true;
break;
case DIST_EXP_TOK:
nextToken( );
if( !parseFloat( f_number ) )
return false;
warp->setDistExp( f_number );
break;
case MAJOR_RADIUS_TOK:
nextToken( );
if( !parseFloat( f_number ) )
return false;
warp->setMajorRadius( f_number );
break;
default:
break;
}
if( mapping)
{
nextToken( );
if( !parseVector( vector ) )
return false;
warp->setOrientation( vector );
parsedFirst = true;
mapping = false;
}
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parsePigment( PMPigment* pigment, bool parseOuter )
{
PMColor c;
PMSolidColor* sc;
int oldConsumed;
if( parseOuter )
{
if( !parseToken( PIGMENT_TOK, "pigment" ) )
return false;
if( !parseToken( '{' ) )
return false;
}
if( m_token == ID_TOK )
{
TQString id( m_pScanner->sValue( ) );
PMSymbol* s = getSymbol( id );
bool skipID = false;
if( s )
if( s->type( ) == PMSymbol::Value )
skipID = true;
if( !skipID )
{
PMDeclare* decl = checkLink( id );
if( decl )
{
if( !pigment->setLinkedObject( decl ) )
printError( i18n( "Wrong declare type" ) );
}
nextToken( );
}
}
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( pigment );
switch( m_token )
{
case '<':
case COLOR_TOK:
case COLOUR_TOK:
case RGB_TOK:
case RGBT_TOK:
case RGBF_TOK:
case RGBFT_TOK:
case RED_TOK:
case GREEN_TOK:
case BLUE_TOK:
case TRANSMIT_TOK:
case FILTER_TOK:
case ID_TOK:
if( parseColor( c ) )
{
sc = new PMSolidColor( m_pPart );
sc->setColor( c );
if( !insertChild( sc, pigment ) )
{
delete sc;
sc = 0;
}
}
break;
case UV_MAPPING_TOK:
nextToken();
pigment->setUVMapping( parseBool( ) );
break;
default:
break;
}
}
while( oldConsumed != m_consumedTokens );
if( parseOuter )
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseNormal( PMNormal* normal )
{
double f_number;
int oldConsumed;
if( !parseToken( NORMAL_TOK, "normal" ) )
return false;
if( !parseToken( '{' ) )
return false;
if( m_token == ID_TOK )
{
TQString id( m_pScanner->sValue( ) );
PMDeclare* decl = checkLink( id );
if( decl )
{
if( !normal->setLinkedObject( decl ) )
printError( i18n( "Wrong declare type" ) );
}
nextToken( );
}
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( normal );
switch( m_token )
{
case BUMP_SIZE_TOK:
nextToken( );
if( !parseFloat( f_number ) )
return false;
normal->enableBumpSize( true );
normal->setBumpSize( f_number );
break;
case ACCURACY_TOK:
nextToken( );
if( !parseFloat( f_number ) )
return false;
normal->setAccuracy( f_number );
break;
case UV_MAPPING_TOK:
nextToken( );
normal->setUVMapping( parseBool( ) );
default:
break;
}
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseTextureMap( PMTextureMap* textureMap )
{
int oldConsumed;
double f_number1;
PMTexture* texture;
TQValueList<double> mapValues;
if( !parseToken( TEXTURE_MAP_TOK, "texture_map" ) )
return false;
if( !parseToken( '{' ) )
return false;
if( m_token == ID_TOK )
{
TQString id( m_pScanner->sValue( ) );
PMDeclare* decl = checkLink( id );
if( decl )
{
if( !textureMap->setLinkedObject( decl ) )
printError( i18n( "Wrong declare type" ) );
}
nextToken( );
}
do
{
oldConsumed = m_consumedTokens;
if( m_token == '[' )
{
nextToken( );
if( !parseFloat( f_number1 ) )
return false;
mapValues.append( f_number1 );
texture = new PMTexture( m_pPart );
parseTexture( texture, false );
if( !insertChild( texture, textureMap ) )
delete texture;
if( !parseToken( ']' ) )
return false;
}
}
while( oldConsumed != m_consumedTokens );
textureMap->setMapValues( mapValues );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parsePigmentMap( PMPigmentMap* pigmentMap )
{
int oldConsumed;
double f_number1;
PMPigment* pigment;
TQValueList<double> mapValues;
if( !parseToken( PIGMENT_MAP_TOK, "pigment_map" ) )
return false;
if( !parseToken( '{' ) )
return false;
if( m_token == ID_TOK )
{
TQString id( m_pScanner->sValue( ) );
PMDeclare* decl = checkLink( id );
if( decl )
{
if( !pigmentMap->setLinkedObject( decl ) )
printError( i18n( "Wrong declare type" ) );
}
nextToken( );
}
do
{
oldConsumed = m_consumedTokens;
if( m_token == '[' )
{
nextToken( );
if( !parseFloat( f_number1 ) )
return false;
mapValues.append( f_number1 );
pigment = new PMPigment( m_pPart );
parsePigment( pigment, false );
if( !insertChild( pigment, pigmentMap ) )
delete pigment;
if( !parseToken( ']' ) )
return false;
}
}
while( oldConsumed != m_consumedTokens );
pigmentMap->setMapValues( mapValues );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseNormalMap( PMNormalMap* normalMap )
{
int oldConsumed;
double f_number1;
PMNormal* normal;
TQValueList<double> mapValues;
if( !parseToken( NORMAL_MAP_TOK, "normal_map" ) )
return false;
if( !parseToken( '{' ) )
return false;
if( m_token == ID_TOK )
{
TQString id( m_pScanner->sValue( ) );
PMDeclare* decl = checkLink( id );
if( decl )
{
if( !normalMap->setLinkedObject( decl ) )
printError( i18n( "Wrong declare type" ) );
}
nextToken( );
}
do
{
oldConsumed = m_consumedTokens;
// If we find '}' no need to search for an entry
if( m_token != '}' && parseToken( '[' ) )
{
if( !parseFloat( f_number1 ) )
return false;
mapValues.append( f_number1 );
normal = new PMNormal( m_pPart );
if( !parseNormal( normal ) )
{
delete normal;
return false;
}
if( !insertChild( normal, normalMap ) )
delete normal;
if( !parseToken( ']' ) )
return false;
}
}
while( oldConsumed != m_consumedTokens );
normalMap->setMapValues( mapValues );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseBumpMap( PMBumpMap* bumpMap )
{
int oldConsumed;
int i_number;
double f_number;
if( !parseToken( BUMP_MAP_TOK, "bump_map" ) )
return false;
if( !parseToken( '{' ) )
return false;
// Parse the bitmap type
if( m_token != STRING_TOK )
{
switch( m_token )
{
case GIF_TOK:
bumpMap->setBitmapType( PMBumpMap::BitmapGif );
nextToken( );
break;
case TGA_TOK:
bumpMap->setBitmapType( PMBumpMap::BitmapTga );
nextToken( );
break;
case IFF_TOK:
bumpMap->setBitmapType( PMBumpMap::BitmapIff );
nextToken( );
break;
case PPM_TOK:
bumpMap->setBitmapType( PMBumpMap::BitmapPpm );
nextToken( );
break;
case PGM_TOK:
bumpMap->setBitmapType( PMBumpMap::BitmapPgm );
nextToken( );
break;
case PNG_TOK:
bumpMap->setBitmapType( PMBumpMap::BitmapPng );
nextToken( );
break;
case SYS_TOK:
bumpMap->setBitmapType( PMBumpMap::BitmapSys );
nextToken( );
break;
default:
printError( i18n( "Unknown bitmap type" ) );
return false;
}
}
// Parse the bitmap file name
if( m_token != STRING_TOK )
{
printError( i18n( "Expecting a file name." ) );
return false;
}
else
{
bumpMap->setBitmapFileName( m_pScanner->sValue( ) );
nextToken( );
}
do
{
oldConsumed = m_consumedTokens;
switch( m_token )
{
case ONCE_TOK:
nextToken( );
bumpMap->enableOnce( true );
break;
case MAP_TYPE_TOK:
nextToken( );
if( !parseInt( i_number ) )
return false;
switch( i_number )
{
case 0:
bumpMap->setMapType( PMBumpMap::MapPlanar );
break;
case 1:
bumpMap->setMapType( PMBumpMap::MapSpherical );
break;
case 2:
bumpMap->setMapType( PMBumpMap::MapCylindrical );
break;
case 5:
bumpMap->setMapType( PMBumpMap::MapToroidal );
break;
}
break;
case INTERPOLATE_TOK:
nextToken( );
if( !parseInt( i_number ) )
return false;
switch( i_number )
{
case 2:
bumpMap->setInterpolateType( PMBumpMap::InterpolateBilinear );
break;
case 4:
bumpMap->setInterpolateType( PMBumpMap::InterpolateNormalized );
break;
}
break;
case USE_INDEX_TOK:
nextToken( );
bumpMap->enableUseIndex( true );
break;
case BUMP_SIZE_TOK:
nextToken( );
if( !parseFloat( f_number ) )
return false;
bumpMap->setBumpSize( f_number );
break;
default:
break;
}
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseMaterialMap( PMMaterialMap* materialMap )
{
int oldConsumed;
int i_number;
if( !parseToken( MATERIAL_MAP_TOK, "material_map" ) )
return false;
if( !parseToken( '{' ) )
return false;
// Parse the bitmap type
if( m_token != STRING_TOK )
{
switch( m_token )
{
case GIF_TOK:
materialMap->setBitmapType( PMMaterialMap::BitmapGif );
nextToken( );
break;
case TGA_TOK:
materialMap->setBitmapType( PMMaterialMap::BitmapTga );
nextToken( );
break;
case IFF_TOK:
materialMap->setBitmapType( PMMaterialMap::BitmapIff );
nextToken( );
break;
case PPM_TOK:
materialMap->setBitmapType( PMMaterialMap::BitmapPpm );
nextToken( );
break;
case PGM_TOK:
materialMap->setBitmapType( PMMaterialMap::BitmapPgm );
nextToken( );
break;
case PNG_TOK:
materialMap->setBitmapType( PMMaterialMap::BitmapPng );
nextToken( );
break;
case SYS_TOK:
materialMap->setBitmapType( PMMaterialMap::BitmapSys );
nextToken( );
break;
default:
printError( i18n( "Unknown bitmap type" ) );
return false;
}
}
// Parse the bitmap file name
if( m_token != STRING_TOK )
{
printError( i18n( "Expecting a file name." ) );
return false;
}
else
{
materialMap->setBitmapFileName( m_pScanner->sValue( ) );
nextToken( );
}
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( materialMap );
switch( m_token )
{
case ONCE_TOK:
nextToken( );
materialMap->enableOnce( true );
break;
case MAP_TYPE_TOK:
nextToken( );
if( !parseInt( i_number ) )
return false;
switch( i_number )
{
case 0:
materialMap->setMapType( PMMaterialMap::MapPlanar );
break;
case 1:
materialMap->setMapType( PMMaterialMap::MapSpherical );
break;
case 2:
materialMap->setMapType( PMMaterialMap::MapCylindrical );
break;
case 5:
materialMap->setMapType( PMMaterialMap::MapToroidal );
break;
}
break;
case INTERPOLATE_TOK:
nextToken( );
if( !parseInt( i_number ) )
return false;
switch( i_number )
{
case 2:
materialMap->setInterpolateType( PMMaterialMap::InterpolateBilinear );
break;
case 4:
materialMap->setInterpolateType( PMMaterialMap::InterpolateNormalized );
break;
}
break;
default:
break;
}
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseSlopeMap( PMSlopeMap* slopeMap )
{
int oldConsumed;
double f_number1;
PMSlope* slope;
TQValueList<double> mapValues;
if( !parseToken( SLOPE_MAP_TOK, "slope_map" ) )
return false;
if( !parseToken( '{' ) )
return false;
if( m_token == ID_TOK )
{
TQString id( m_pScanner->sValue( ) );
PMDeclare* decl = checkLink( id );
if( decl )
{
if( !slopeMap->setLinkedObject( decl ) )
printError( i18n( "Wrong declare type" ) );
}
nextToken( );
}
do
{
oldConsumed = m_consumedTokens;
// If we find '}' no need to search for an entry
if( m_token != '}' && parseToken( '[' ) )
{
if( !parseFloat( f_number1 ) )
return false;
mapValues.append( f_number1 );
slope = new PMSlope( m_pPart );
if( !parseSlope( slope ) )
{
delete slope;
return false;
}
if( !insertChild( slope, slopeMap ) )
delete slope;
if( !parseToken( ']' ) )
return false;
}
}
while( oldConsumed != m_consumedTokens );
slopeMap->setMapValues( mapValues );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseDensityMap( PMDensityMap* densityMap )
{
int oldConsumed;
double f_number1;
PMDensity* density;
TQValueList<double> mapValues;
if( !parseToken( DENSITY_MAP_TOK, "density_map" ) )
return false;
if( !parseToken( '{' ) )
return false;
if( m_token == ID_TOK )
{
TQString id( m_pScanner->sValue( ) );
PMDeclare* decl = checkLink( id );
if( decl )
{
if( !densityMap->setLinkedObject( decl ) )
printError( i18n( "Wrong declare type" ) );
}
nextToken( );
}
do
{
oldConsumed = m_consumedTokens;
// If we find '}' no need to search for an entry
if( m_token != '}' && parseToken( '[' ) )
{
if( !parseFloat( f_number1 ) )
return false;
mapValues.append( f_number1 );
density = new PMDensity( m_pPart );
if( !parseDensity( density ) )
{
delete density;
return false;
}
if( !insertChild( density, densityMap ) )
delete density;
if( !parseToken( ']' ) )
return false;
}
}
while( oldConsumed != m_consumedTokens );
densityMap->setMapValues( mapValues );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseImageMap( PMImageMap* imageMap )
{
int oldConsumed;
int i_number;
double f_number;
PMPaletteValue newPaletteValue;
TQValueList<PMPaletteValue> l_valuesFilter;
TQValueList<PMPaletteValue> l_valuesTransmit;
if( !parseToken( IMAGE_MAP_TOK, "image_map" ) )
return false;
if( !parseToken( '{' ) )
return false;
// Parse the bitmap type
if( m_token != STRING_TOK )
{
switch( m_token )
{
case GIF_TOK:
imageMap->setBitmapType( PMImageMap::BitmapGif );
nextToken( );
break;
case TGA_TOK:
imageMap->setBitmapType( PMImageMap::BitmapTga );
nextToken( );
break;
case IFF_TOK:
imageMap->setBitmapType( PMImageMap::BitmapIff );
nextToken( );
break;
case PPM_TOK:
imageMap->setBitmapType( PMImageMap::BitmapPpm );
nextToken( );
break;
case PGM_TOK:
imageMap->setBitmapType( PMImageMap::BitmapPgm );
nextToken( );
break;
case PNG_TOK:
imageMap->setBitmapType( PMImageMap::BitmapPng );
nextToken( );
break;
case SYS_TOK:
imageMap->setBitmapType( PMImageMap::BitmapSys );
nextToken( );
break;
default:
printError( i18n( "Unknown bitmap type" ) );
return false;
}
}
// Parse the bitmap file name
if( m_token != STRING_TOK )
{
printError( i18n( "Expecting a file name." ) );
return false;
}
else
{
imageMap->setBitmapFileName( m_pScanner->sValue( ) );
nextToken( );
}
do
{
oldConsumed = m_consumedTokens;
switch( m_token )
{
case TRANSMIT_TOK:
nextToken( );
if( m_token == ALL_TOK )
{
nextToken( );
if( !parseFloat( f_number ) )
return false;
imageMap->enableTransmitAll( true );
imageMap->setTransmitAll( f_number );
}
else
{
if( !parseInt( i_number ) )
return false;
parseToken( ',' );
if( !parseFloat( f_number ) )
return false;
newPaletteValue.setIndex( i_number );
newPaletteValue.setValue( f_number );
l_valuesTransmit.append( newPaletteValue );
}
break;
case FILTER_TOK:
nextToken( );
if( m_token == ALL_TOK )
{
nextToken( );
if( !parseFloat( f_number ) )
return false;
imageMap->enableFilterAll( true );
imageMap->setFilterAll( f_number );
}
else
{
if( !parseInt( i_number ) )
return false;
parseToken( ',' );
if( !parseFloat( f_number ) )
return false;
newPaletteValue.setIndex( i_number );
newPaletteValue.setValue( f_number );
l_valuesFilter.append( newPaletteValue );
}
break;
case ONCE_TOK:
nextToken( );
imageMap->enableOnce( true );
break;
case MAP_TYPE_TOK:
nextToken( );
if( !parseInt( i_number ) )
return false;
switch( i_number )
{
case 0:
imageMap->setMapType( PMImageMap::MapPlanar );
break;
case 1:
imageMap->setMapType( PMImageMap::MapSpherical );
break;
case 2:
imageMap->setMapType( PMImageMap::MapCylindrical );
break;
case 5:
imageMap->setMapType( PMImageMap::MapToroidal );
break;
}
break;
case INTERPOLATE_TOK:
nextToken( );
if( !parseInt( i_number ) )
return false;
switch( i_number )
{
case 2:
imageMap->setInterpolateType( PMImageMap::InterpolateBilinear );
break;
case 4:
imageMap->setInterpolateType( PMImageMap::InterpolateNormalized );
break;
}
break;
default:
break;
}
}
while( oldConsumed != m_consumedTokens );
imageMap->setFilters( l_valuesFilter );
imageMap->setTransmits( l_valuesTransmit );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parsePigmentList( PMPigmentList* pigmentList, int expectedItems )
{
int oldConsumed;
PMPigment* pigment;
do
{
oldConsumed = m_consumedTokens;
pigment = new PMPigment( m_pPart );
if( !parsePigment( pigment ) )
{
delete pigment;
return false;
}
if( !insertChild( pigment, pigmentList ) )
delete pigment;
// In the last entry don't expect a comma
if( expectedItems-- )
if( m_token == ',' )
nextToken( );
}
while( oldConsumed != m_consumedTokens && expectedItems );
return true;
}
bool PMPovrayParser::parseColorList( PMColorList* colorList, int expectedItems )
{
int oldConsumed;
PMColor color;
PMSolidColor* sc;
do
{
oldConsumed = m_consumedTokens;
if( !parseColor( color ) )
{
return false;
}
sc = new PMSolidColor( m_pPart );
sc->setColor( color );
if( !insertChild( sc, colorList ) )
delete sc;
// In the last entry don't expect a comma
if( expectedItems-- )
if( m_token == ',' )
nextToken( );
}
while( oldConsumed != m_consumedTokens && expectedItems );
return true;
}
bool PMPovrayParser::parseNormalList( PMNormalList* normalList, int expectedItems )
{
int oldConsumed;
PMNormal* normal;
do
{
oldConsumed = m_consumedTokens;
normal = new PMNormal( m_pPart );
if( !parseNormal( normal ) )
{
delete normal;
return false;
}
if( !insertChild( normal, normalList ) )
delete normal;
// In the last entry don't expect a comma
if( expectedItems-- )
if( m_token == ',' )
nextToken( );
}
while( oldConsumed != m_consumedTokens && expectedItems );
return true;
}
bool PMPovrayParser::parseTextureList( PMTextureList* textureList, int expectedItems )
{
int oldConsumed;
PMTexture* texture;
do
{
oldConsumed = m_consumedTokens;
texture = new PMTexture( m_pPart );
if( !parseTexture( texture ) )
{
delete texture;
return false;
}
if( !insertChild( texture, textureList ) )
delete texture;
// In the last entry don't expect a comma
if( expectedItems-- )
if( m_token == ',' )
nextToken( );
}
while( oldConsumed != m_consumedTokens && expectedItems );
return true;
}
bool PMPovrayParser::parseDensityList( PMDensityList* densityList, int expectedItems )
{
int oldConsumed;
PMDensity* density;
do
{
oldConsumed = m_consumedTokens;
density = new PMDensity( m_pPart );
if( !parseDensity( density ) )
{
delete density;
return false;
}
if( !insertChild( density, densityList ) )
delete density;
// In the last entry don't expect a comma
if( expectedItems-- )
if( m_token == ',' )
nextToken( );
}
while( oldConsumed != m_consumedTokens && expectedItems );
return true;
}
bool PMPovrayParser::parseColorMap( PMColorMap* colorMap )
{
int oldConsumed;
double f_number1, f_number2;
PMColor color1, color2;
PMSolidColor* solidColor;
PMSolidColor* lastColor = 0;
TQValueList<double> mapValues;
bool newEntry;
bool twoColors;
if( m_token != COLOR_MAP_TOK && m_token != COLOUR_MAP_TOK )
return false;
nextToken( );
if( !parseToken( '{' ) )
return false;
if( m_token == ID_TOK )
{
TQString id( m_pScanner->sValue( ) );
PMDeclare* decl = checkLink( id );
if( decl )
{
if( !colorMap->setLinkedObject( decl ) )
printError( i18n( "Wrong declare type" ) );
}
nextToken( );
}
do
{
oldConsumed = m_consumedTokens;
if( m_token == '[' )
{
nextToken( );
if( !parseFloat( f_number1 ) )
return false;
twoColors = false;
if( m_token == ',' )
{
twoColors = true;
nextToken( );
}
else if( ( m_token == INTEGER_TOK ) || ( m_token == FLOAT_TOK ) )
twoColors = true;
if( twoColors )
{
// Two colors in the same entry
if( parseFloat( f_number2 ) )
{
if( !parseColor( color1 ) )
return false;
if( !parseColor( color2 ) )
return false;
// If the first value doesn't pick up from the previous,
// or the color is different...
newEntry = true;
if( lastColor && !mapValues.isEmpty( ) )
if( ( mapValues.last( ) == f_number1 ) &&
( lastColor->color( ) == color1 ) )
newEntry = false;
if( newEntry )
{
// ... add the two colors in two different entries ...
mapValues.append( f_number1 );
solidColor = new PMSolidColor( m_pPart );
solidColor->setColor( color1 );
if( !insertChild( solidColor, colorMap ) )
delete solidColor;
else
lastColor = solidColor;
mapValues.append( f_number2 );
solidColor = new PMSolidColor( m_pPart );
solidColor->setColor( color2 );
if( !insertChild( solidColor, colorMap ) )
delete solidColor;
else
lastColor = solidColor;
}
else
{
// ... else just add the last value and color
mapValues.append( f_number2 );
solidColor = new PMSolidColor( m_pPart );
solidColor->setColor( color2 );
if( !insertChild( solidColor, colorMap ) )
delete solidColor;
else
lastColor = solidColor;
}
}
}
else
{
// Only one color in the entry
if( !parseColor( color1 ) )
return false;
mapValues.append( f_number1 );
solidColor = new PMSolidColor( m_pPart );
solidColor->setColor( color1 );
if( !insertChild( solidColor, colorMap ) )
delete solidColor;
else
lastColor = solidColor;
}
if( !parseToken( ']' ) )
return false;
}
}
while( oldConsumed != m_consumedTokens );
colorMap->setMapValues( mapValues );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseSkySphere( PMSkySphere* sky )
{
int oldConsumed;
if( !parseToken( SKY_SPHERE_TOK, "sky_sphere" ) )
return false;
if( !parseToken( '{' ) )
return false;
if( m_token == ID_TOK )
{
TQString id( m_pScanner->sValue( ) );
PMDeclare* decl = checkLink( id );
if( decl )
{
if( !sky->setLinkedObject( decl ) )
printError( i18n( "Wrong declare type" ) );
}
nextToken( );
}
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( sky );
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseRainbow( PMRainbow* rainbow )
{
PMVector vector;
double f_number;
int oldConsumed;
if( !parseToken( RAINBOW_TOK, "rainbow" ) )
return false;
if( !parseToken( '{' ) )
return false;
if( m_token == ID_TOK )
{
TQString id( m_pScanner->sValue( ) );
PMDeclare* decl = checkLink( id );
if( decl )
{
if( !rainbow->setLinkedObject( decl ) )
printError( i18n( "Wrong declare type" ) );
}
nextToken( );
}
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( rainbow );
switch( m_token )
{
case DIRECTION_TOK:
nextToken( );
if( parseVector( vector ) )
{
rainbow->enableDirection( true );
rainbow->setDirection( vector );
}
break;
case ANGLE_TOK:
nextToken( );
if( parseFloat( f_number ) )
{
rainbow->enableAngle( true );
rainbow->setAngle( f_number );
}
break;
case WIDTH_TOK:
nextToken( );
if( parseFloat( f_number ) )
{
rainbow->enableWidth( true );
rainbow->setWidth( f_number );
}
break;
case DISTANCE_TOK:
nextToken( );
if( parseFloat( f_number ) )
{
rainbow->enableDistance( true );
rainbow->setDistance( f_number );
}
break;
case JITTER_TOK:
nextToken( );
if( parseFloat( f_number ) )
{
rainbow->enableJitter( true );
rainbow->setJitter( f_number );
}
break;
case UP_TOK:
nextToken( );
if( parseVector( vector ) )
{
rainbow->enableUp( true );
rainbow->setUp( vector );
}
break;
case ARC_ANGLE_TOK:
nextToken( );
if( parseFloat( f_number ) )
{
rainbow->enableArcAngle( true );
rainbow->setArcAngle( f_number );
}
break;
case FALLOFF_ANGLE_TOK:
nextToken( );
if( parseFloat( f_number ) )
{
rainbow->enableFalloffAngle( true );
rainbow->setFalloffAngle( f_number );
}
break;
default:
break;
}
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseFog( PMFog* fog )
{
PMColor color;
PMVector vector;
double f_number;
int i_number;
int fog_type;
int oldConsumed;
if( !parseToken( FOG_TOK, "fog" ) )
return false;
if( !parseToken( '{' ) )
return false;
if( m_token == ID_TOK )
{
TQString id( m_pScanner->sValue( ) );
PMDeclare* decl = checkLink( id );
if( decl )
{
if( !fog->setLinkedObject( decl ) )
printError( i18n( "Wrong declare type" ) );
}
nextToken( );
}
fog_type = 1;
if( parseToken( FOG_TYPE_TOK, "fog_type" ) )
{
if( !parseInt( i_number ) )
return false;
fog_type = i_number;
}
do
{
oldConsumed = m_consumedTokens;
switch( m_token )
{
case DISTANCE_TOK:
nextToken( );
if( parseFloat( f_number ) )
fog->setDistance( f_number );
break;
case '<':
case COLOR_TOK:
case COLOUR_TOK:
case RGB_TOK:
case RGBT_TOK:
case RGBF_TOK:
case RGBFT_TOK:
case RED_TOK:
case GREEN_TOK:
case BLUE_TOK:
case TRANSMIT_TOK:
case FILTER_TOK:
case ID_TOK:
if( parseColor( color ) )
fog->setColor( color );
break;
case TURBULENCE_TOK:
nextToken( );
fog->enableTurbulence( true );
if( !parseVector( vector ) )
return false;
fog->setValueVector( vector );
break;
case OCTAVES_TOK:
nextToken( );
if( !parseInt( i_number ) )
return false;
fog->setOctaves( i_number );
break;
case OMEGA_TOK:
nextToken( );
if( !parseFloat( f_number ) )
return false;
fog->setOmega( f_number );
break;
case LAMBDA_TOK:
nextToken( );
if( !parseFloat( f_number ) )
return false;
fog->setLambda( f_number );
break;
case TURB_DEPTH_TOK:
nextToken( );
if( !parseFloat( f_number ) )
return false;
fog->setDepth( f_number );
break;
case FOG_OFFSET_TOK:
nextToken( );
fog_type = 2;
if( parseFloat( f_number ) )
fog->setFogOffset( f_number );
break;
case FOG_ALT_TOK:
nextToken( );
fog_type = 2;
if( parseFloat( f_number ) )
fog->setFogAlt( f_number );
break;
case UP_TOK:
nextToken( );
fog_type = 2;
if( !parseVector( vector ) )
return false;
fog->setUp( vector );
break;
default:
break;
}
// Only parseChildObjects() if the token is not turbulence, because this
// function parses that token.
if( m_token != TURBULENCE_TOK )
parseChildObjects( fog );
}
while( oldConsumed != m_consumedTokens );
fog->setFogType( fog_type );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseMedia( PMMedia* media )
{
PMColor color;
double f_number;
int i_number;
int oldConsumed, oldConsumed1;
if( !parseToken( MEDIA_TOK, "media" ) )
return false;
if( !parseToken( '{' ) )
return false;
if( m_token == ID_TOK )
{
TQString id( m_pScanner->sValue( ) );
PMDeclare* decl = checkLink( id );
if( decl )
{
if( !media->setLinkedObject( decl ) )
printError( i18n( "Wrong declare type" ) );
}
nextToken( );
}
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( media );
switch( m_token )
{
case METHOD_TOK:
nextToken( );
if( parseInt( i_number ) )
media->setMethod( i_number );
break;
case INTERVALS_TOK:
nextToken( );
if( parseInt( i_number ) )
media->setIntervals( i_number );
break;
case SAMPLES_TOK:
nextToken( );
if( parseInt( i_number ) )
media->setSamplesMin( i_number );
parseToken( ',' );
if( parseInt( i_number ) )
media->setSamplesMax( i_number );
break;
case CONFIDENCE_TOK:
nextToken( );
if( parseFloat( f_number ) )
media->setConfidence( f_number );
break;
case VARIANCE_TOK:
nextToken( );
if( parseFloat( f_number ) )
media->setVariance( f_number );
break;
case RATIO_TOK:
nextToken( );
if( parseFloat( f_number ) )
media->setRatio( f_number );
break;
case AA_LEVEL_TOK:
nextToken( );
if ( parseInt( i_number ) )
media->setAALevel( i_number );
break;
case AA_THRESHOLD_TOK:
nextToken( );
if ( parseFloat( f_number ) )
media->setAAThreshold( f_number );
break;
case ABSORPTION_TOK:
nextToken( );
if( parseColor( color ) )
{
media->enableAbsorption( true );
media->setAbsorption( color );
}
break;
case EMISSION_TOK:
nextToken( );
media->enableEmission( true );
if( parseColor( color ) )
media->setEmission( color );
break;
case SCATTERING_TOK:
nextToken( );
parseToken( '{' );
media->enableScattering( true );
if( parseInt( i_number ) )
media->setScatteringType( i_number );
parseToken( ',' );
if( parseColor( color ) )
media->setScatteringColor( color );
do
{
oldConsumed1 = m_consumedTokens;
switch( m_token )
{
case ECCENTRICITY_TOK:
nextToken( );
if( parseFloat( f_number ) )
media->setScatteringEccentricity( f_number );
break;
case EXTINCTION_TOK:
nextToken( );
if( parseFloat( f_number ) )
media->setScatteringExtinction( f_number );
break;
default:
break;
}
}
while( oldConsumed1 != m_consumedTokens );
parseToken( '}' );
break;
default:
break;
}
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseDensity( PMDensity* density )
{
int oldConsumed;
if( !parseToken( DENSITY_TOK, "density" ) )
return false;
if( !parseToken( '{' ) )
return false;
if( m_token == ID_TOK )
{
TQString id( m_pScanner->sValue( ) );
PMDeclare* decl = checkLink( id );
if( decl )
{
if( !density->setLinkedObject( decl ) )
printError( i18n( "Wrong declare type" ) );
}
nextToken( );
}
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( density );
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseInterior( PMInterior* interior )
{
double f_number;
int i_number;
int oldConsumed;
if( !parseToken( INTERIOR_TOK, "interior" ) )
return false;
if( !parseToken( '{' ) )
return false;
if( m_token == ID_TOK )
{
TQString id( m_pScanner->sValue( ) );
PMDeclare* decl = checkLink( id );
if( decl )
{
if( !interior->setLinkedObject( decl ) )
printError( i18n( "Wrong declare type" ) );
}
nextToken( );
}
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( interior );
switch( m_token )
{
case IOR_TOK:
nextToken( );
if( parseFloat( f_number ) )
{
interior->enableIor( true );
interior->setIor( f_number );
}
break;
case CAUSTICS_TOK:
nextToken( );
if( parseFloat( f_number ) )
{
interior->enableCaustics( true );
interior->setCaustics( f_number );
}
break;
case DISPERSION_TOK:
nextToken( );
if ( parseFloat( f_number ) )
{
interior->enableDispersion( true );
interior->setDispersion( f_number );
}
break;
case DISPERSION_SAMPLES_TOK:
nextToken( );
if ( parseInt( i_number ) )
{
interior->enableDispSamples( true );
interior->setDispSamples( i_number );
}
break;
case FADE_DISTANCE_TOK:
nextToken( );
if( parseFloat( f_number ) )
{
interior->enableFadeDistance( true );
interior->setFadeDistance( f_number );
}
break;
case FADE_POWER_TOK:
nextToken( );
if( parseFloat( f_number ) )
{
interior->enableFadePower( true );
interior->setFadePower( f_number );
}
break;
default:
break;
}
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseMaterial( PMMaterial* material )
{
int oldConsumed;
if( !parseToken( MATERIAL_TOK, "material" ) )
return false;
if( !parseToken( '{' ) )
return false;
if( m_token == ID_TOK )
{
TQString id( m_pScanner->sValue( ) );
PMDeclare* decl = checkLink( id );
if( decl )
{
if( !material->setLinkedObject( decl ) )
printError( i18n( "Wrong declare type" ) );
}
nextToken( );
}
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( material );
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseSlope( PMSlope* slope )
{
double f_number;
if( !parseToken( '<' ) )
return false;
if( !parseFloat( f_number ) )
return false;
slope->setHeight( f_number );
if( !parseToken( ',' ) )
return false;
if( !parseFloat( f_number ) )
return false;
slope->setSlope( f_number );
if( !parseToken( '>' ) )
return false;
return true;
}
bool PMPovrayParser::parseGlobalSettings( PMGlobalSettings* globalsettings )
{
PMColor color;
double f_number;
int i_number;
int oldConsumed;
// Initial global settings tokens
if( !parseToken( GLOBAL_SETTINGS_TOK, "global_settings" ) )
return false;
if( !parseToken( '{' ) )
return false;
// Parse global settings tokens
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( globalsettings );
switch( m_token )
{
case ADC_BAILOUT_TOK:
nextToken( );
if( parseFloat( f_number ) )
globalsettings->setAdcBailout( f_number );
break;
case AMBIENT_LIGHT_TOK:
nextToken( );
if( parseColor( color ) )
globalsettings->setAmbientLight( color );
break;
case ASSUMED_GAMMA_TOK:
nextToken( );
if( parseFloat( f_number ) )
globalsettings->setAssumedGamma( f_number );
break;
case HF_GRAY_16_TOK:
nextToken( );
switch( m_token )
{
case ON_TOK:
globalsettings->setHfGray16( true );
nextToken( );
break;
case OFF_TOK:
globalsettings->setHfGray16( false );
nextToken( );
break;
default:
break;
}
break;
case IRID_WAVELENGTH_TOK:
nextToken( );
if( parseColor( color ) )
globalsettings->setIridWaveLength( color );
break;
case MAX_INTERSECTIONS_TOK:
nextToken( );
if( parseInt( i_number ) )
globalsettings->setMaxIntersections( i_number );
break;
case MAX_TRACE_LEVEL_TOK:
nextToken( );
if( parseInt( i_number ) )
globalsettings->setMaxTraceLevel( i_number );
break;
case NUMBER_OF_WAVES_TOK:
nextToken( );
if( parseInt( i_number ) )
globalsettings->setNumberWaves( i_number );
break;
case NOISE_GENERATOR_TOK:
nextToken( );
if ( parseInt( i_number ) )
globalsettings->setNoiseGenerator(
( PMGlobalSettings::PMNoiseType ) ( i_number - 1 ) );
break;
}
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseFinish( PMFinish* finish )
{
PMColor color;
double f_number;
int oldConsumed, oldConsumed1;
// Initial finish tokens "finish {"
if( !parseToken( FINISH_TOK, "finish" ) )
return false;
if( !parseToken( '{' ) )
return false;
// Parse a possible declare link identifier
if( m_token == ID_TOK )
{
TQString id( m_pScanner->sValue( ) );
PMDeclare* decl = checkLink( id );
if( decl )
{
if( !finish->setLinkedObject( decl ) )
printError( i18n( "Wrong declare type" ) );
}
nextToken( );
}
// Parse finish tokens
do
{
oldConsumed = m_consumedTokens;
switch( m_token )
{
case AMBIENT_TOK:
nextToken( );
finish->enableAmbient( true );
if( parseColor( color ) )
finish->setAmbientColor( color );
break;
case DIFFUSE_TOK:
nextToken( );
if( parseFloat( f_number ) )
{
finish->enableDiffuse( true );
finish->setDiffuse( f_number );
}
break;
case BRILLIANCE_TOK:
nextToken( );
if( parseFloat( f_number ) )
{
finish->enableBrilliance( true );
finish->setBrilliance( f_number );
}
break;
case PHONG_TOK:
nextToken( );
if( parseFloat( f_number ) )
{
finish->enablePhong( true );
finish->setPhong( f_number );
}
break;
case PHONG_SIZE_TOK:
nextToken( );
if( parseFloat( f_number ) )
{
finish->enablePhongSize( true );
finish->setPhongSize( f_number );
}
break;
case METALLIC_TOK:
nextToken( );
finish->enableMetallic( true );
finish->setMetallic( 1.0 );
if( parseFloat( f_number, true ) )
finish->setMetallic( f_number );
break;
case SPECULAR_TOK:
nextToken( );
if( parseFloat( f_number ) )
{
finish->enableSpecular( true );
finish->setSpecular( f_number );
}
break;
case ROUGHNESS_TOK:
nextToken( );
if( parseFloat( f_number ) )
{
finish->enableRoughness( true );
finish->setRoughness( f_number );
}
break;
case CRAND_TOK:
nextToken( );
if( parseFloat( f_number ) )
{
finish->enableCrand( true );
finish->setCrand( f_number );
}
break;
case CONSERVE_ENERGY_TOK:
nextToken( );
finish->setConserveEnergy( parseBool( ) );
break;
case REFLECTION_TOK:
nextToken( );
finish->enableReflection( true );
if( !parseToken( '{' ) )
{
printError( i18n( "Using Old Reflection Syntax" ) );
if( parseColor( color ) )
finish->setReflectionColor( color );
}
else if( parseColor( color ) )
{
if( parseToken( ',' ) )
{
finish->enableReflectionMin( true );
finish->setReflectionMinColor( color );
if( parseColor( color ) )
finish->setReflectionColor( color );
else
return false;
}
else
finish->setReflectionColor( color );
do
{
oldConsumed1 = m_consumedTokens;
switch( m_token )
{
case FRESNEL_TOK:
nextToken( );
finish->setReflectionFresnel( parseBool( ) );
break;
case FALLOFF_TOK:
nextToken( );
if( parseFloat( f_number ) )
{
finish->enableRefFalloff( true );
finish->setReflectionFalloff( f_number );
}
break;
case EXPONENT_TOK:
nextToken( );
if( parseFloat( f_number ) )
{
finish->enableRefExponent( true );
finish->setReflectionExponent( f_number );
}
break;
case METALLIC_TOK:
nextToken( );
if ( parseFloat( f_number ) )
{
finish->enableRefMetallic( true );
finish->setReflectionMetallic( f_number );
}
break;
default:
break;
}
}
while( oldConsumed1 != m_consumedTokens );
parseToken( '}' );
}
else
return false;
break;
case REFLECTION_EXPONENT_TOK:
nextToken( );
if ( parseFloat( f_number ) )
{
finish->enableRefExponent( true );
finish->setReflectionExponent( f_number );
}
break;
case IRID_TOK:
nextToken( );
parseToken( '{' );
finish->setIrid( true );
if( parseFloat( f_number ) )
finish->setIridAmount( f_number );
do
{
oldConsumed1 = m_consumedTokens;
switch( m_token )
{
case THICKNESS_TOK:
nextToken( );
if( parseFloat( f_number ) )
finish->setIridThickness( f_number );
break;
case TURBULENCE_TOK:
nextToken( );
if( parseFloat( f_number ) )
finish->setIridTurbulence( f_number );
break;
default:
break;
}
}
while( oldConsumed1 != m_consumedTokens );
parseToken( '}' );
break;
default:
break;
}
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseDeclare( PMDeclare* decl )
{
PMObject* child = 0;
PMTexture* texture = 0;
bool error = false;
switch( m_token )
{
case OBJECT_TOK:
error = !parseObject( decl );
break;
// finite solid
case BLOB_TOK:
child = new PMBlob( m_pPart );
error = !parseBlob( ( PMBlob* ) child );
break;
case BOX_TOK:
child = new PMBox( m_pPart );
error = !parseBox( ( PMBox* ) child );
break;
case CONE_TOK:
child = new PMCone( m_pPart );
error = !parseCone( ( PMCone* ) child );
break;
case CYLINDER_TOK:
child = new PMCylinder( m_pPart );
error = !parseCylinder( ( PMCylinder* ) child );
break;
case HEIGHT_FIELD_TOK:
child = new PMHeightField( m_pPart );
error = !parseHeightField( ( PMHeightField* ) child );
break;
case JULIA_FRACTAL_TOK:
child = new PMJuliaFractal( m_pPart );
error = !parseJuliaFractal( ( PMJuliaFractal* ) child );
break;
case LATHE_TOK:
child = new PMLathe( m_pPart );
error = !parseLathe( ( PMLathe* ) child );
break;
case PRISM_TOK:
child = new PMPrism( m_pPart );
error = !parsePrism( ( PMPrism* ) child );
break;
case SPHERE_TOK:
child = new PMSphere( m_pPart );
error = !parseSphere( ( PMSphere* ) child );
break;
case SUPERELLIPSOID_TOK:
child = new PMSuperquadricEllipsoid( m_pPart );
error = !parseSqe( ( PMSuperquadricEllipsoid* ) child );
break;
case SOR_TOK:
child = new PMSurfaceOfRevolution( m_pPart );
error = !parseSor( ( PMSurfaceOfRevolution* ) child );
break;
case TEXT_TOK:
child = new PMText( m_pPart );
error = !parseText( ( PMText* ) child );
break;
case TORUS_TOK:
child = new PMTorus( m_pPart );
error = !parseTorus( ( PMTorus* ) child );
break;
// finite patch
case BICUBIC_PATCH_TOK:
child = new PMBicubicPatch( m_pPart );
error = !parseBicubicPatch( ( PMBicubicPatch* ) child );
break;
case DISC_TOK:
child = new PMDisc( m_pPart );
error = !parseDisc( ( PMDisc* ) child );
break;
case TRIANGLE_TOK:
case SMOOTH_TRIANGLE_TOK:
child = new PMTriangle( m_pPart );
error = !parseTriangle( ( PMTriangle* ) child );
break;
// infinite solid
case PLANE_TOK:
child = new PMPlane( m_pPart );
error = !parsePlane( ( PMPlane* ) child );
break;
case QUADRIC_TOK:
case CUBIC_TOK:
case QUARTIC_TOK:
case POLY_TOK:
child = new PMPolynom( m_pPart );
error = !parsePolynom( ( PMPolynom* ) child );
break;
// csg
case UNION_TOK:
case DIFFERENCE_TOK:
case INTERSECTION_TOK:
case MERGE_TOK:
child = new PMCSG( m_pPart );
error = !parseCSG( ( PMCSG* ) child );
break;
// textures
case TEXTURE_TOK:
while( m_token == TEXTURE_TOK )
{
texture = new PMTexture( m_pPart );
if( !parseTexture( texture ) )
error = true;
if( !insertChild( texture, decl ) )
{
delete texture;
texture = 0;
}
}
break;
case PIGMENT_TOK:
child = new PMPigment( m_pPart );
error = !parsePigment( ( PMPigment* ) child );
break;
case NORMAL_TOK:
child = new PMNormal( m_pPart );
error = !parseNormal( ( PMNormal* ) child );
break;
case FINISH_TOK:
child = new PMFinish( m_pPart );
error = !parseFinish( ( PMFinish* ) child );
break;
case TEXTURE_MAP_TOK:
child = new PMTextureMap( m_pPart );
error = !parseTextureMap( ( PMTextureMap* ) child );
break;
case PIGMENT_MAP_TOK:
child = new PMPigmentMap( m_pPart );
error = !parsePigmentMap( ( PMPigmentMap* ) child );
break;
case COLOR_MAP_TOK:
case COLOUR_MAP_TOK:
child = new PMColorMap( m_pPart );
error = !parseColorMap( ( PMColorMap* ) child );
break;
case NORMAL_MAP_TOK:
child = new PMNormalMap( m_pPart );
error = !parseNormalMap( ( PMNormalMap* ) child );
break;
case SLOPE_MAP_TOK:
child = new PMSlopeMap( m_pPart );
error = !parseSlopeMap( ( PMSlopeMap* ) child );
break;
case DENSITY_MAP_TOK:
child = new PMDensityMap( m_pPart );
error = !parseDensityMap( ( PMDensityMap* ) child );
break;
case INTERIOR_TOK:
child = new PMInterior( m_pPart );
error = !parseInterior( ( PMInterior* ) child );
break;
case MEDIA_TOK:
child = new PMMedia( m_pPart );
error = !parseMedia( ( PMMedia* ) child );
break;
case DENSITY_TOK:
child = new PMDensity( m_pPart );
error = !parseDensity( ( PMDensity* ) child );
break;
case MATERIAL_TOK:
child = new PMMaterial( m_pPart );
error = !parseMaterial( ( PMMaterial* ) child );
break;
case SKY_SPHERE_TOK:
child = new PMSkySphere( m_pPart );
error = !parseSkySphere( ( PMSkySphere* ) child );
break;
case RAINBOW_TOK:
child = new PMRainbow( m_pPart );
error = !parseRainbow( ( PMRainbow* ) child );
break;
case FOG_TOK:
child = new PMFog( m_pPart );
error = !parseFog( ( PMFog* ) child );
break;
// misc
case LIGHT_SOURCE_TOK:
child = new PMLight( m_pPart );
error = !parseLight( ( PMLight* ) child );
break;
case ISOSURFACE_TOK:
child = new PMIsoSurface( m_pPart );
error = !parseIsoSurface( ( PMIsoSurface* ) child );
break;
case PHOTONS_TOK:
child = new PMPhotons( m_pPart );
error = !parsePhotons( ( PMPhotons* ) child );
break;
case LIGHT_GROUP_TOK:
child = new PMLightGroup( m_pPart );
error = !parseLightGroup( ( PMLightGroup* ) child );
break;
case INTERIOR_TEXTURE_TOK:
child = new PMInteriorTexture( m_pPart );
error = !parseInteriorTexture( ( PMInteriorTexture* ) child );
break;
case SPHERE_SWEEP_TOK:
child = new PMSphereSweep( m_pPart );
error = !parseSphereSweep( ( PMSphereSweep* ) child );
break;
case MESH_TOK:
child = new PMMesh( m_pPart );
error = !parseMesh( ( PMMesh* ) child );
break;
}
if( child )
{
if( !insertChild( child, decl ) )
{
delete child;
child = 0;
}
}
return !error;
}
bool PMPovrayParser::parseObject( PMCompositeObject* parent )
{
PMObject* child;
bool error = false;
if( !parseToken( OBJECT_TOK, "object" ) )
return false;
if( parseToken( '{' ) )
{
switch( m_token )
{
case ID_TOK:
child = new PMObjectLink( m_pPart );
error = !parseObjectLink( ( PMObjectLink* ) child );
if( !insertChild( child, parent ) )
delete child;
break;
default:
{
PMObject* lastChild = 0;
if( parent )
lastChild = parent->lastChild( );
else
lastChild = m_pResultList->last( );
error = !parseChildObjects( parent, 1 );
if( !error )
{
PMObject* newLast = 0;
if( parent )
newLast = parent->lastChild( );
else
newLast = m_pResultList->last( );
if( newLast && ( newLast != lastChild ) &&
newLast->isA( "CompositeObject" ) )
{
// one child was parsed
// append all following objects
error = !parseChildObjects( ( PMCompositeObject* ) newLast );
}
else
{
printError( i18n( "One graphical object expected" ) );
error = true;
}
}
break;
}
}
if( !parseToken( '}' ))
error = true;
}
else
error = true;
return !error;
}
bool PMPovrayParser::parseObjectLink( PMObjectLink* link )
{
int oldConsumed;
if( m_token != ID_TOK )
{
printExpected( "identifier", m_pScanner->sValue( ) );
return false;
}
TQString id( m_pScanner->sValue( ) );
PMDeclare* decl = checkLink( id );
if( decl )
{
if( !link->setLinkedObject( decl ) )
printError( i18n( "Wrong declare type" ) );
}
nextToken( );
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( link );
parseObjectModifiers( link );
}
while( oldConsumed != m_consumedTokens );
return true;
}
bool PMPovrayParser::parseIsoSurface( PMIsoSurface* iso )
{
PMVector vector;
double f;
int i;
int oldConsumed;
if( !parseToken( ISOSURFACE_TOK, "isosurface" ) )
return false;
if( !parseToken( '{' ) )
return false;
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( iso );
parseObjectModifiers( iso );
switch( m_token )
{
case FUNCTION_TOK:
nextToken( );
if( m_token != '{' )
{
printExpected( '{', m_pScanner->sValue( ) );
return false;
}
m_pScanner->scanFunction( );
nextToken( );
if( m_token != FUNCTION_TOK )
return false;
iso->setFunction( TQString( m_pScanner->sValue( ) ).simplifyWhiteSpace( ) );
nextToken( );
parseToken( '}' );
break;
case CONTAINED_BY_TOK:
nextToken( );
if( !parseToken( '{' ) )
return false;
if( m_token == BOX_TOK )
{
iso->setContainedBy( PMIsoSurface::Box );
nextToken( );
parseToken( '{' );
if( parseVector( vector ) )
iso->setCorner1( vector );
parseToken( ',' );
if( parseVector( vector ) )
iso->setCorner2( vector );
if( !parseToken( '}' ) )
return false;
}
else if( m_token == SPHERE_TOK )
{
iso->setContainedBy( PMIsoSurface::Sphere );
nextToken( );
parseToken( '{' );
if( parseVector( vector ) )
iso->setCenter( vector );
parseToken( ',' );
if( parseFloat( f ) )
iso->setRadius( f );
if( !parseToken( '}' ) )
return false;
}
else
{
printUnexpected( m_pScanner->sValue( ) );
return false;
}
if( !parseToken( '}' ) )
return false;
break;
case THRESHOLD_TOK:
nextToken( );
if( parseFloat( f ) )
iso->setThreshold( f );
break;
case ACCURACY_TOK:
nextToken( );
if( parseFloat( f ) )
iso->setAccuracy( f );
break;
case MAX_GRADIENT_TOK:
nextToken( );
if( parseFloat( f ) )
iso->setMaxGradient( f );
break;
case EVALUATE_TOK:
nextToken( );
iso->setEvaluate( true );
if( parseFloat( f ) )
{
iso->setEvaluateValue( 0, f );
if( parseToken( ',' ) && parseFloat( f ) )
{
iso->setEvaluateValue( 1, f );
if( parseToken( ',' ) && parseFloat( f ) )
iso->setEvaluateValue( 2, f );
}
}
break;
case OPEN_TOK:
nextToken( );
iso->setOpen( true );
break;
case MAX_TRACE_TOK:
nextToken( );
if( parseInt( i ) )
iso->setMaxTrace( i );
break;
case ALL_INTERSECTIONS_TOK:
nextToken( );
iso->setAllIntersections( true );
break;
default:
break;
}
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseRadiosity( PMRadiosity* rad )
{
double f;
int i;
int oldConsumed;
if( !parseToken( RADIOSITY_TOK, "radiosity" ) )
return false;
if( !parseToken( '{' ) )
return false;
do
{
oldConsumed = m_consumedTokens;
switch( m_token )
{
case ADC_BAILOUT_TOK:
nextToken( );
if( parseFloat( f ) )
rad->setAdcBailout( f );
break;
case ALWAYS_SAMPLE_TOK:
nextToken( );
rad->setAlwaysSample( parseBool( ) );
break;
case BRIGHTNESS_TOK:
nextToken( );
if( parseFloat( f ) )
rad->setBrightness( f );
break;
case COUNT_TOK:
nextToken( );
if( parseInt( i ) )
rad->setCount( i );
break;
case ERROR_BOUND_TOK:
nextToken( );
if( parseFloat( f ) )
rad->setErrorBound( f );
break;
case GRAY_THRESHOLD_TOK:
nextToken( );
if( parseFloat( f ) )
rad->setGrayThreshold( f );
break;
case LOW_ERROR_FACTOR_TOK:
nextToken( );
if( parseFloat( f ) )
rad->setLowErrorFactor( f );
break;
case MAX_SAMPLE_TOK:
nextToken( );
if ( parseFloat( f ) )
rad->setMaxSample( f );
break;
case MEDIA_TOK:
nextToken( );
rad->setMedia( parseBool( ) );
break;
case MINIMUM_REUSE_TOK:
nextToken( );
if( parseFloat( f ) )
rad->setMinimumReuse( f );
break;
case NEAREST_COUNT_TOK:
nextToken( );
if( parseInt( i ) )
rad->setNearestCount( i );
break;
case NORMAL_TOK:
nextToken( );
rad->setNormal( parseBool( ) );
break;
case PRETRACE_START_TOK:
nextToken( );
if( parseFloat( f ) )
rad->setPretraceStart( f );
break;
case PRETRACE_END_TOK:
nextToken( );
if( parseFloat( f ) )
rad->setPretraceEnd( f );
break;
case RECURSION_LIMIT_TOK:
nextToken( );
if( parseInt( i) )
rad->setRecursionLimit( i );
break;
}
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseGlobalPhotons( PMGlobalPhotons* gp )
{
double f;
int i;
int oldConsumed;
if( !parseToken( PHOTONS_TOK, "photons" ) )
return false;
if( !parseToken( '{' ) )
return false;
do
{
oldConsumed = m_consumedTokens;
switch( m_token )
{
case SPACING_TOK:
gp->setNumberType( PMGlobalPhotons::Spacing );
nextToken( );
if ( parseFloat( f ) )
gp->setSpacing( f );
break;
case COUNT_TOK:
gp->setNumberType( PMGlobalPhotons::Count );
nextToken( );
if ( parseInt( i ) )
gp->setCount( i );
break;
case GATHER_TOK:
nextToken( );
if ( parseInt( i ) )
{
gp->setGatherMin( i );
if ( parseToken( ',' ) && parseInt( i ) )
gp->setGatherMax( i );
}
break;
case MEDIA_TOK:
nextToken( );
if ( parseInt( i ) )
{
gp->setMediaMaxSteps( i );
if ( parseToken( ',' ) && parseFloat( f ) )
gp->setMediaFactor( f );
}
case JITTER_TOK:
nextToken( );
if ( parseFloat( f ) )
gp->setJitter( f );
break;
case MAX_TRACE_LEVEL_TOK:
nextToken( );
gp->setMaxTraceLevelGlobal( false );
if ( parseInt( i ) )
gp->setMaxTraceLevel( i );
break;
case ADC_BAILOUT_TOK:
nextToken( );
gp->setAdcBailoutGlobal( false );
if ( parseFloat( f ) )
gp->setAdcBailout( f );
break;
case AUTOSTOP_TOK:
nextToken( );
if ( parseFloat( f ) )
gp->setAutostop( f );
break;
case EXPAND_THRESHOLDS_TOK:
nextToken( );
if ( parseFloat( f ) )
{
gp->setExpandIncrease( f );
if ( parseToken( ',' ) && parseInt( i ) )
gp->setExpandMin( i );
}
break;
case RADIUS_TOK:
nextToken( );
if ( parseFloat( f ) )
{
gp->setRadiusGather( f );
if ( parseToken( ',' ) && parseFloat( f ) )
{
gp->setRadiusGatherMulti( f );
if ( parseToken( ',' ) && parseFloat( f ) )
{
gp->setRadiusMedia( f );
if ( parseToken( ',' ) && parseFloat( f ) )
gp->setRadiusMediaMulti( f );
}
}
}
break;
}
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parsePhotons( PMPhotons* p )
{
double f;
int oldConsumed;
if( !parseToken( PHOTONS_TOK, "photons" ) )
return false;
if( !parseToken( '{' ) )
return false;
p->setTarget( false );
do
{
oldConsumed = m_consumedTokens;
switch( m_token )
{
case TARGET_TOK:
nextToken( );
p->setTarget( true );
if ( parseFloat( f ) )
p->setSpacingMulti( f );
break;
case REFRACTION_TOK:
nextToken( );
p->setRefraction( parseBool( ) );
break;
case REFLECTION_TOK:
nextToken( );
p->setReflection( parseBool( ) );
break;
case COLLECT_TOK:
nextToken( );
p->setCollect( parseBool( ) );
break;
case PASS_THROUGH_TOK:
nextToken( );
p->setPassThrough( parseBool( ) );
break;
case AREA_LIGHT_TOK:
nextToken( );
p->setAreaLight( parseBool( ) );
break;
}
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseLightGroup( PMLightGroup* lg )
{
int oldConsumed;
if ( !parseToken( LIGHT_GROUP_TOK, "light_group" ) )
return false;
if( !parseToken( '{' ) )
return false;
do
{
oldConsumed = m_consumedTokens;
if ( m_token == GLOBAL_LIGHTS_TOK )
{
nextToken( );
lg->setGlobalLights( parseBool( ) );
}
else
{
parseChildObjects( lg );
parseObjectModifiers( lg );
}
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseInteriorTexture( PMInteriorTexture* it )
{
int oldConsumed;
if( !parseToken( INTERIOR_TEXTURE_TOK, "interior_texture" ) )
return false;
if( !parseToken( '{' ) )
return false;
do
{
oldConsumed = m_consumedTokens;
parseChildObjects( it );
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseSphereSweep( PMSphereSweep* ss )
{
int oldConsumed, numspheres;
TQValueList<PMVector> points;
TQValueList<double> radii;
PMVector point;
double f;
if( !parseToken( SPHERE_SWEEP_TOK, "sphere_sweep" ) )
return false;
if( !parseToken( '{' ) )
return false;
nextToken( );
switch ( m_token )
{
case LINEAR_SPLINE_TOK:
ss->setSplineType( PMSphereSweep::LinearSpline );
break;
case B_SPLINE_TOK:
ss->setSplineType( PMSphereSweep::BSpline );
break;
case CUBIC_SPLINE_TOK:
ss->setSplineType( PMSphereSweep::CubicSpline );
break;
default:
return false;
}
if ( !parseInt( numspheres ) )
return false;
for ( int i = 0; i < numspheres; ++i )
{
if ( !parseVector( point ) )
return false;
points.append( point );
if ( !parseToken( ',' ) )
return false;
if ( !parseFloat( f ) )
return false;
radii.append( f );
}
ss->setPoints( points );
ss->setRadii( radii );
do
{
oldConsumed = m_consumedTokens;
if ( m_token == TOLERANCE_TOK )
{
nextToken( );
if ( !parseFloat( f ) )
return false;
ss->setTolerance( f );
}
else
{
parseObjectModifiers( ss );
}
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}
bool PMPovrayParser::parseMesh( PMMesh* m )
{
int oldConsumed;
PMVector vector;
if( !parseToken( MESH_TOK, "mesh" ) )
return false;
if( !parseToken( '{' ) )
return false;
do
{
oldConsumed = m_consumedTokens;
if ( m_token == HIERARCHY_TOK )
{
nextToken( );
m->setHierarchy( parseBool( ) );
}
else if ( m_token == INSIDE_VECTOR_TOK )
{
nextToken( );
if ( !parseVector( vector ) )
return false;
m->enableInsideVector( true );
m->setInsideVector( vector );
}
else
{
parseChildObjects( m );
parseObjectModifiers( m );
}
}
while( oldConsumed != m_consumedTokens );
if( !parseToken( '}' ) )
return false;
return true;
}