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.
7214 lines
191 KiB
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 <klocale.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 SQR_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;
|
|
}
|