Skip to content

Commit 7ffe150

Browse files
committed
Restore turbulent pattern performance as discussed in GitHub issue #48.
1 parent 741fae5 commit 7ffe150

File tree

4 files changed

+96
-21
lines changed

4 files changed

+96
-21
lines changed

changes.txt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ Changes between 3.7.1-beta.4 and 3.7.1-beta.5
2828
=============================================
2929

3030
The focus of this version has been on improving the Visual Studio 2015-based
31-
Windows build process.
31+
Windows build process, as well as reclaiming some performance lost earlier
32+
during the development of 3.7.1.
3233

3334
Fixed or Mitigated Bugs
3435
-----------------------
@@ -40,8 +41,9 @@ Reported via GitHub:
4041

4142
Miscellaneous:
4243

43-
- Restored user-defined function VM performance roughly back to levels of
44-
3.7.0.
44+
- Restored performance of user-defined functions (e.g. in isosurfaces) as
45+
well as patterns with special turbulence handling (agate, marble, wood,
46+
spiral1, spiral2).
4547

4648
Other Noteworthy
4749
----------------

source/core/material/pattern.cpp

Lines changed: 61 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
/// ----------------------------------------------------------------------------
1515
///
1616
/// Persistence of Vision Ray Tracer ('POV-Ray') version 3.7.
17-
/// Copyright 1991-2016 Persistence of Vision Raytracer Pty. Ltd.
17+
/// Copyright 1991-2017 Persistence of Vision Raytracer Pty. Ltd.
1818
///
1919
/// POV-Ray is free software: you can redistribute it and/or modify
2020
/// it under the terms of the GNU Affero General Public License as
@@ -202,7 +202,7 @@ static ColourBlendMapConstPtr gpDefaultBlendMap_Wood (new ColourBlendMap(2, gaDe
202202
* Static functions
203203
******************************************************************************/
204204

205-
static const ClassicTurbulence* SearchForTurb(const WarpList warps);
205+
static inline const ClassicTurbulence* GetTurb(const WarpList warps);
206206
static unsigned short ReadUShort(IStream *pInFile);
207207
static unsigned int ReadUInt(IStream *pInFile);
208208

@@ -268,6 +268,11 @@ BasicPattern::~BasicPattern()
268268
Destroy_Warps(warps);
269269
}
270270

271+
bool BasicPattern::Precompute()
272+
{
273+
return true;
274+
}
275+
271276
int BasicPattern::GetNoiseGen(const TraceThreadData *pThread) const
272277
{
273278
int noise_gen = noiseGenerator;
@@ -387,8 +392,15 @@ bool AveragePattern::HasSpecialTurbulenceHandling() const { return false; }
387392

388393

389394
AgatePattern::AgatePattern() : agateTurbScale(1.0) {}
395+
396+
bool AgatePattern::Precompute()
397+
{
398+
return (!warps.empty() && dynamic_cast<ClassicTurbulence*>(*warps.begin()));
399+
}
400+
390401
ColourBlendMapConstPtr AgatePattern::GetDefaultBlendMap() const { return gpDefaultBlendMap_Agate; }
391402

403+
392404
ColourBlendMapConstPtr BozoPattern::GetDefaultBlendMap() const { return gpDefaultBlendMap_Bozo; }
393405

394406
BrickPattern::BrickPattern() : brickSize(8.0,3.0,4.5), mortar(0.5-EPSILON*2.0) {}
@@ -557,7 +569,18 @@ DBL ImagePattern::EvaluateRaw(const Vector3d& EPoint, const Intersection *pIsect
557569
}
558570

559571

560-
MarblePattern::MarblePattern() { waveType = kWaveType_Triangle; }
572+
MarblePattern::MarblePattern() :
573+
hasTurbulence() // no explicit default; set by Precompute()
574+
{
575+
waveType = kWaveType_Triangle;
576+
}
577+
578+
bool MarblePattern::Precompute()
579+
{
580+
hasTurbulence = (!warps.empty() && dynamic_cast<ClassicTurbulence*>(*warps.begin()));
581+
return true;
582+
}
583+
561584
ColourBlendMapConstPtr MarblePattern::GetDefaultBlendMap() const { return gpDefaultBlendMap_Marble; }
562585

563586

@@ -649,18 +672,38 @@ SlopePattern::SlopePattern() :
649672

650673

651674
SpiralPattern::SpiralPattern() :
652-
arms() // no explicit default; must be set by caller
675+
arms(), // no explicit default; must be set by caller
676+
hasTurbulence() // no explicit default; set by Precompute()
653677
{
654678
waveType = kWaveType_Triangle;
655679
}
656680

681+
bool SpiralPattern::Precompute()
682+
{
683+
hasTurbulence = (!warps.empty() && dynamic_cast<ClassicTurbulence*>(*warps.begin()));
684+
return true;
685+
}
686+
687+
657688
ColourBlendMapConstPtr SquarePattern::GetDefaultBlendMap() const { return gpDefaultBlendMap_Square; }
658689
unsigned int SquarePattern::NumDiscreteBlendMapEntries() const { return 4; }
659690

660691
ColourBlendMapConstPtr TriangularPattern::GetDefaultBlendMap() const { return gpDefaultBlendMap_Triangular; }
661692
unsigned int TriangularPattern::NumDiscreteBlendMapEntries() const { return 6; }
662693

663-
WoodPattern::WoodPattern() { waveType = kWaveType_Triangle; }
694+
695+
WoodPattern::WoodPattern() :
696+
hasTurbulence() // no explicit default; set by Precompute()
697+
{
698+
waveType = kWaveType_Triangle;
699+
}
700+
701+
bool WoodPattern::Precompute()
702+
{
703+
hasTurbulence = (!warps.empty() && dynamic_cast<ClassicTurbulence*>(*warps.begin()));
704+
return true;
705+
}
706+
664707
ColourBlendMapConstPtr WoodPattern::GetDefaultBlendMap() const { return gpDefaultBlendMap_Wood; }
665708

666709

@@ -1076,12 +1119,11 @@ template void BlendMap<TexturePtr> ::Search (DBL value, EntryConstPtr& rpPrev,
10761119
*
10771120
******************************************************************************/
10781121

1079-
static const ClassicTurbulence *SearchForTurb(const WarpList warps)
1122+
static inline const ClassicTurbulence *GetTurb(const WarpList warps)
10801123
{
1081-
if(warps.empty())
1082-
return NULL;
1083-
else
1084-
return dynamic_cast<const ClassicTurbulence*>(*warps.begin());
1124+
POV_PATTERN_ASSERT(!warps.empty());
1125+
POV_PATTERN_ASSERT(dynamic_cast<const ClassicTurbulence*>(*warps.begin()));
1126+
return static_cast<const ClassicTurbulence*>(*warps.begin());
10851127
}
10861128

10871129

@@ -5345,8 +5387,7 @@ DBL AgatePattern::EvaluateRaw(const Vector3d& EPoint, const Intersection *pIsect
53455387
register DBL noise, turb_val;
53465388
const ClassicTurbulence* Turb;
53475389

5348-
Turb=SearchForTurb(warps);
5349-
POV_PATTERN_ASSERT(Turb != NULL); // Parser must make sure that a pattern-associated classic turbulence warp exists.
5390+
Turb = GetTurb(warps);
53505391

53515392
turb_val = agateTurbScale * Turbulence(EPoint,Turb,noise_generator);
53525393

@@ -7790,8 +7831,9 @@ DBL MarblePattern::EvaluateRaw(const Vector3d& EPoint, const Intersection *pIsec
77907831
register DBL turb_val;
77917832
const ClassicTurbulence *Turb;
77927833

7793-
if ((Turb=SearchForTurb(warps)) != NULL)
7834+
if (hasTurbulence)
77947835
{
7836+
Turb = GetTurb(warps);
77957837
turb_val = Turb->Turbulence[X] * Turbulence(EPoint,Turb,GetNoiseGen(pThread));
77967838
}
77977839
else
@@ -8357,8 +8399,9 @@ DBL Spiral1Pattern::EvaluateRaw(const Vector3d& EPoint, const Intersection *pIse
83578399
DBL z = EPoint[Z];
83588400
const ClassicTurbulence *Turb;
83598401

8360-
if ((Turb=SearchForTurb(warps)) != NULL)
8402+
if (hasTurbulence)
83618403
{
8404+
Turb = GetTurb(warps);
83628405
turb_val = Turb->Turbulence[X] * Turbulence(EPoint,Turb,GetNoiseGen(pThread));
83638406
}
83648407
else
@@ -8433,8 +8476,9 @@ DBL Spiral2Pattern::EvaluateRaw(const Vector3d& EPoint, const Intersection *pIse
84338476
DBL z = EPoint[Z];
84348477
const ClassicTurbulence *Turb;
84358478

8436-
if ((Turb=SearchForTurb(warps)) != NULL)
8479+
if (hasTurbulence)
84378480
{
8481+
Turb = GetTurb(warps);
84388482
turb_val = Turb->Turbulence[X] * Turbulence(EPoint,Turb,GetNoiseGen(pThread));
84398483
}
84408484
else
@@ -8611,8 +8655,9 @@ DBL WoodPattern::EvaluateRaw(const Vector3d& EPoint, const Intersection *pIsecti
86118655
DBL y=EPoint[Y];
86128656
const ClassicTurbulence *Turb;
86138657

8614-
if ((Turb=SearchForTurb(warps)) != NULL)
8658+
if (hasTurbulence)
86158659
{
8660+
Turb = GetTurb(warps);
86168661
DTurbulence (WoodTurbulence, EPoint, Turb);
86178662
point[X] = cycloidal((x + WoodTurbulence[X]) * Turb->Turbulence[X]);
86188663
point[Y] = cycloidal((y + WoodTurbulence[Y]) * Turb->Turbulence[Y]);

source/core/material/pattern.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
/// @parblock
99
///
1010
/// Persistence of Vision Ray Tracer ('POV-Ray') version 3.7.
11-
/// Copyright 1991-2016 Persistence of Vision Raytracer Pty. Ltd.
11+
/// Copyright 1991-2017 Persistence of Vision Raytracer Pty. Ltd.
1212
///
1313
/// POV-Ray is free software: you can redistribute it and/or modify
1414
/// it under the terms of the GNU Affero General Public License as
@@ -202,6 +202,12 @@ struct BasicPattern
202202
///
203203
virtual PatternPtr Clone() const = 0;
204204

205+
/// Test the pattern parameters and precompute derived values.
206+
///
207+
/// @return True if pattern parameters are within reasonable limits.
208+
///
209+
virtual bool Precompute();
210+
205211
/// Evaluates the pattern at a given point in space.
206212
///
207213
/// This method implements the actual pattern computation code, and for obvious reasons any derived class must
@@ -384,6 +390,7 @@ struct AgatePattern : public ContinuousPattern
384390

385391
AgatePattern();
386392
virtual PatternPtr Clone() const { return BasicPattern::Clone(*this); }
393+
virtual bool Precompute();
387394
virtual DBL EvaluateRaw(const Vector3d& EPoint, const Intersection *pIsection, const Ray *pRay, TraceThreadData *pThread) const;
388395
virtual ColourBlendMapConstPtr GetDefaultBlendMap() const;
389396
};
@@ -583,9 +590,14 @@ struct MarblePattern : public ContinuousPattern
583590
{
584591
MarblePattern();
585592
virtual PatternPtr Clone() const { return BasicPattern::Clone(*this); }
593+
virtual bool Precompute();
586594
virtual DBL EvaluateRaw(const Vector3d& EPoint, const Intersection *pIsection, const Ray *pRay, TraceThreadData *pThread) const;
587595
virtual ColourBlendMapConstPtr GetDefaultBlendMap() const;
588596
virtual bool HasSpecialTurbulenceHandling() const;
597+
598+
protected:
599+
600+
bool hasTurbulence : 1;
589601
};
590602

591603
/// Base class for the noise-based patterns.
@@ -777,9 +789,14 @@ struct WoodPattern : public ContinuousPattern
777789
{
778790
WoodPattern();
779791
virtual PatternPtr Clone() const { return BasicPattern::Clone(*this); }
792+
virtual bool Precompute();
780793
virtual DBL EvaluateRaw(const Vector3d& EPoint, const Intersection *pIsection, const Ray *pRay, TraceThreadData *pThread) const;
781794
virtual ColourBlendMapConstPtr GetDefaultBlendMap() const;
782795
virtual bool HasSpecialTurbulenceHandling() const;
796+
797+
protected:
798+
799+
bool hasTurbulence : 1;
783800
};
784801

785802
/// Implements the `wrinkles` pattern.
@@ -997,7 +1014,12 @@ struct SpiralPattern : public ContinuousPattern
9971014

9981015
SpiralPattern();
9991016
virtual PatternPtr Clone() const = 0;
1017+
virtual bool Precompute();
10001018
virtual DBL EvaluateRaw(const Vector3d& EPoint, const Intersection *pIsection, const Ray *pRay, TraceThreadData *pThread) const = 0;
1019+
1020+
protected:
1021+
1022+
bool hasTurbulence : 1;
10011023
};
10021024

10031025
/// Implements the `spiral1` pattern.

source/parser/parser_materials.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
/// @parblock
99
///
1010
/// Persistence of Vision Ray Tracer ('POV-Ray') version 3.7.
11-
/// Copyright 1991-2016 Persistence of Vision Raytracer Pty. Ltd.
11+
/// Copyright 1991-2017 Persistence of Vision Raytracer Pty. Ltd.
1212
///
1313
/// POV-Ray is free software: you can redistribute it and/or modify
1414
/// it under the terms of the GNU Affero General Public License as
@@ -2160,6 +2160,9 @@ void Parser::Parse_Pattern (PATTERN_T *New, BlendMapTypeId TPat_Type)
21602160
}
21612161

21622162
VerifyPattern(New->pattern);
2163+
2164+
if (!New->pattern->Precompute())
2165+
Error("Unspecified parse error in pattern.");
21632166
}
21642167

21652168

@@ -5496,6 +5499,9 @@ void Parser::Parse_PatternFunction(TPATTERN *New)
54965499
END_EXPECT
54975500

54985501
VerifyPattern(New->pattern);
5502+
5503+
if (!New->pattern->Precompute())
5504+
Error("Unspecified parse error in pattern.");
54995505
}
55005506

55015507
}

0 commit comments

Comments
 (0)