#ifndef __OpenCSG__sequencer_h__
#define __OpenCSG__sequencer_h__
#include "opencsgConfig.h"
#include <algorithm>
namespace OpenCSG {
class Sequencer
{
public:
virtual ~Sequencer()
{
}
virtual size_t index(size_t position) const = 0;
virtual size_t size() const = 0;
virtual size_t sizeForDepthComplexity(size_t dc) const = 0;
protected:
Sequencer(size_t numElems)
: n(numElems)
{
}
size_t n;
};
class SimpleSequencer : public Sequencer
{
public:
SimpleSequencer(size_t numElems)
: Sequencer(numElems)
{
}
virtual size_t index(size_t position) const
{
return position % n;
}
virtual size_t size() const
{
return n * (n - 1) + 1;
}
virtual size_t sizeForDepthComplexity(size_t dc) const
{
return n * dc;
}
};
class BouncingSequencer : public Sequencer
{
public:
BouncingSequencer(size_t numElems)
: Sequencer(numElems)
{
}
virtual size_t index(size_t position) const
{
if (n == 1)
return 0;
size_t wave = position % (n + n - 2);
if (wave < n)
return wave;
else
return (n + n - 2) - wave;
}
virtual size_t size() const
{
return n * (n - 1) + 1;
}
virtual size_t sizeForDepthComplexity(size_t dc) const
{
return (dc & 1) == 1
? (dc - 1) * (n - 1) + n
: dc * (n - 1) + 1;
}
};
class SchoenfieldSequencer : public Sequencer
{
public:
SchoenfieldSequencer(size_t numElems)
: Sequencer(numElems)
{
}
virtual size_t index(size_t position) const
{
if (n == 1)
return 0;
if (n == 2)
return position & 1;
if (position < n)
return position;
else if ((position - 1) % (n - 1) == 0)
return 0;
else
return (position * (n - 2) / (n - 1)) % (n - 1) + 1;
}
virtual size_t size() const
{
if (n == 1)
return 1;
if (n == 2)
return 3;
return n * n - 2 * n + 4;
}
virtual size_t sizeForDepthComplexity(size_t dc) const
{
return std::min(size(), n * dc);
}
};
}
#endif