Geometrize 1.0
C++ library for geometrizing images into geometric primitives
Public Member Functions | Private Attributes | Static Private Attributes | List of all members
geometrize::Model::ModelImpl Class Reference
Collaboration diagram for geometrize::Model::ModelImpl:
Collaboration graph
[legend]

Public Member Functions

 ModelImpl (const geometrize::Bitmap &target)
 
 ModelImpl (const geometrize::Bitmap &target, const geometrize::Bitmap &initial)
 
 ~ModelImpl ()=default
 
ModelImploperator= (const ModelImpl &)=delete
 
 ModelImpl (const ModelImpl &)=delete
 
void reset (const geometrize::rgba backgroundColor)
 
std::int32_t getWidth () const
 
std::int32_t getHeight () const
 
std::vector< geometrize::StategetHillClimbState (const std::function< std::shared_ptr< geometrize::Shape >(void)> shapeCreator, const std::uint8_t alpha, const std::uint32_t shapeCount, const std::uint32_t maxShapeMutations, std::uint32_t maxThreads, const geometrize::core::EnergyFunction energyFunction)
 
std::vector< geometrize::ShapeResultstep (const std::function< std::shared_ptr< geometrize::Shape >(void)> shapeCreator, const std::uint8_t alpha, const std::uint32_t shapeCount, const std::uint32_t maxShapeMutations, const std::uint32_t maxThreads, const geometrize::core::EnergyFunction &energyFunction, const geometrize::ShapeAcceptancePreconditionFunction &addShapePrecondition)
 
geometrize::ShapeResult drawShape (const std::shared_ptr< geometrize::Shape > shape, const geometrize::rgba color)
 
geometrize::BitmapgetTarget ()
 
geometrize::BitmapgetCurrent ()
 
const geometrize::BitmapgetTarget () const
 
const geometrize::BitmapgetCurrent () const
 
void setSeed (const std::uint32_t seed)
 

Private Attributes

geometrize::Bitmap m_target
 The target bitmap, the bitmap we aim to approximate. More...
 
geometrize::Bitmap m_current
 The current bitmap. More...
 
double m_lastScore
 Score derived from calculating the difference between bitmaps. More...
 
std::atomic< std::uint32_t > m_baseRandomSeed
 The base value used for seeding the random number generator (the one the user has control over). More...
 
std::atomic< std::uint32_t > m_randomSeedOffset
 Seed used for random number generation. Note: incremented by each std::async call used for model stepping. More...
 

Static Private Attributes

static const std::uint32_t defaultMaxThreads {4}
 

Constructor & Destructor Documentation

◆ ModelImpl() [1/3]

geometrize::Model::ModelImpl::ModelImpl ( const geometrize::Bitmap target)
inline
46 :
47 m_target{target},
52 {}
std::uint32_t getHeight() const
getHeight Gets the height of the bitmap.
Definition: bitmap.cpp:25
std::uint32_t getWidth() const
getWidth Gets the width of the bitmap.
Definition: bitmap.cpp:20
geometrize::Bitmap m_target
The target bitmap, the bitmap we aim to approximate.
Definition: model.cpp:213
double m_lastScore
Score derived from calculating the difference between bitmaps.
Definition: model.cpp:215
std::atomic< std::uint32_t > m_randomSeedOffset
Seed used for random number generation. Note: incremented by each std::async call used for model step...
Definition: model.cpp:218
geometrize::Bitmap m_current
The current bitmap.
Definition: model.cpp:214
std::atomic< std::uint32_t > m_baseRandomSeed
The base value used for seeding the random number generator (the one the user has control over).
Definition: model.cpp:217
geometrize::rgba getAverageImageColor(const geometrize::Bitmap &image)
getAverageImageColor Computes the average RGB color of the pixels in the bitmap.
Definition: commonutil.cpp:35
double differenceFull(const geometrize::Bitmap &first, const geometrize::Bitmap &second)
differenceFull Calculates the root-mean-square error between two bitmaps.
Definition: core.cpp:174

◆ ModelImpl() [2/3]

geometrize::Model::ModelImpl::ModelImpl ( const geometrize::Bitmap target,
const geometrize::Bitmap initial 
)
inline
Here is the call graph for this function:

◆ ~ModelImpl()

geometrize::Model::ModelImpl::~ModelImpl ( )
default

◆ ModelImpl() [3/3]

geometrize::Model::ModelImpl::ModelImpl ( const ModelImpl )
delete

Member Function Documentation

◆ drawShape()

geometrize::ShapeResult geometrize::Model::ModelImpl::drawShape ( const std::shared_ptr< geometrize::Shape shape,
const geometrize::rgba  color 
)
inline
176 {
177 const std::vector<geometrize::Scanline> lines{shape->rasterize(*shape)};
178 const geometrize::Bitmap before{m_current};
179 geometrize::drawLines(m_current, color, lines);
180
182
183 const geometrize::ShapeResult result{m_lastScore, color, shape};
184 return result;
185 }
The Bitmap class is a helper class for working with bitmap data.
Definition: bitmap.h:16
double differencePartial(const geometrize::Bitmap &target, const geometrize::Bitmap &before, const geometrize::Bitmap &after, const double score, const std::vector< Scanline > &lines)
differencePartial Calculates the root-mean-square error between the parts of the two bitmaps within t...
Definition: core.cpp:198
void drawLines(geometrize::Bitmap &image, const geometrize::rgba color, const std::vector< geometrize::Scanline > &lines)
drawLines Draws scanlines onto an image.
Definition: rasterizer.cpp:74
The ShapeResult struct is a container for info about a shape added to the model.
Definition: shaperesult.h:20
Here is the call graph for this function:

◆ getCurrent() [1/2]

geometrize::Bitmap & geometrize::Model::ModelImpl::getCurrent ( )
inline
193 {
194 return m_current;
195 }

◆ getCurrent() [2/2]

const geometrize::Bitmap & geometrize::Model::ModelImpl::getCurrent ( ) const
inline
203 {
204 return m_current;
205 }

◆ getHeight()

std::int32_t geometrize::Model::ModelImpl::getHeight ( ) const
inline
81 {
82 return m_target.getHeight();
83 }
Here is the call graph for this function:

◆ getHillClimbState()

std::vector< geometrize::State > geometrize::Model::ModelImpl::getHillClimbState ( const std::function< std::shared_ptr< geometrize::Shape >(void)>  shapeCreator,
const std::uint8_t  alpha,
const std::uint32_t  shapeCount,
const std::uint32_t  maxShapeMutations,
std::uint32_t  maxThreads,
const geometrize::core::EnergyFunction  energyFunction 
)
inline
92 {
93 // Ensure that the maximum number of threads is a sane value
94 if(maxThreads == 0) {
95 maxThreads = std::thread::hardware_concurrency();
96 if(maxThreads == 0) {
97 assert(0 && "Failed to get the number of concurrent threads supported by the implementation");
98 maxThreads = defaultMaxThreads;
99 }
100 }
101
102 std::vector<std::future<geometrize::State>> futures{maxThreads};
103 for(std::uint32_t i = 0; i < futures.size(); i++) {
104 std::future<geometrize::State> handle{std::async(std::launch::async, [&](const std::uint32_t seed, const double lastScore) {
105 // Ensure that the results of the random generation are the same between tasks with identical settings
106 // The RNG is thread-local and std::async may use a thread pool (which is why this is necessary)
107 // Note this implementation requires maxThreads to be the same between tasks for each task to produce the same results.
109
111 return core::bestHillClimbState(shapeCreator, alpha, shapeCount, maxShapeMutations, m_target, m_current, buffer, lastScore, energyFunction);
113 futures[i] = std::move(handle);
114 }
115
116 std::vector<geometrize::State> states;
117
118 for(auto& f : futures) {
119 try {
120 states.emplace_back(f.get());
121 } catch(std::exception& e) {
122 assert(0 && "Encountered exception when getting hill climb state");
123 std::cout << e.what() << std::endl;
124 throw e;
125 } catch (...) {
126 assert(0 && "Encountered exception when getting hill climb state");
127 throw;
128 }
129 }
130 return states;
131 }
static const std::uint32_t defaultMaxThreads
Definition: model.cpp:216
void seedRandomGenerator(const std::uint32_t seed)
seedRandomGenerator Seeds the (thread-local) random number generators.
Definition: commonutil.cpp:24
geometrize::State bestHillClimbState(const std::function< std::shared_ptr< geometrize::Shape >(void)> &shapeCreator, const std::uint32_t alpha, const std::uint32_t n, const std::uint32_t age, const geometrize::Bitmap &target, const geometrize::Bitmap &current, geometrize::Bitmap &buffer, const double lastScore, const EnergyFunction &customEnergyFunction)
bestHillClimbState Gets the best state using a hill climbing algorithm.
Definition: core.cpp:233
Here is the call graph for this function:
Here is the caller graph for this function:

◆ getTarget() [1/2]

geometrize::Bitmap & geometrize::Model::ModelImpl::getTarget ( )
inline
188 {
189 return m_target;
190 }

◆ getTarget() [2/2]

const geometrize::Bitmap & geometrize::Model::ModelImpl::getTarget ( ) const
inline
198 {
199 return m_target;
200 }

◆ getWidth()

std::int32_t geometrize::Model::ModelImpl::getWidth ( ) const
inline
76 {
77 return m_target.getWidth();
78 }
Here is the call graph for this function:

◆ operator=()

ModelImpl & geometrize::Model::ModelImpl::operator= ( const ModelImpl )
delete

◆ reset()

void geometrize::Model::ModelImpl::reset ( const geometrize::rgba  backgroundColor)
inline
70 {
71 m_current.fill(backgroundColor);
73 }
void fill(geometrize::rgba color)
fill Fills the bitmap with the given color.
Definition: bitmap.cpp:55
Here is the call graph for this function:

◆ setSeed()

void geometrize::Model::ModelImpl::setSeed ( const std::uint32_t  seed)
inline
208 {
209 m_baseRandomSeed = seed;
210 }

◆ step()

std::vector< geometrize::ShapeResult > geometrize::Model::ModelImpl::step ( const std::function< std::shared_ptr< geometrize::Shape >(void)>  shapeCreator,
const std::uint8_t  alpha,
const std::uint32_t  shapeCount,
const std::uint32_t  maxShapeMutations,
const std::uint32_t  maxThreads,
const geometrize::core::EnergyFunction energyFunction,
const geometrize::ShapeAcceptancePreconditionFunction addShapePrecondition 
)
inline
141 {
142 std::vector<geometrize::State> states{getHillClimbState(shapeCreator, alpha, shapeCount, maxShapeMutations, maxThreads, energyFunction)};
143 if(states.empty()) {
144 assert(0 && "Failed to get a hill climb state");
145 return {};
146 }
147
148 std::vector<geometrize::State>::iterator it = std::min_element(states.begin(), states.end(), [](const geometrize::State& a, const geometrize::State& b) {
149 return a.m_score < b.m_score;
150 });
151
152 // Draw the shape onto the image
153 const std::shared_ptr<geometrize::Shape> shape = it->m_shape;
154 const std::vector<geometrize::Scanline> lines{shape->rasterize(*shape)};
156 const geometrize::Bitmap before{m_current};
157 geometrize::drawLines(m_current, color, lines);
158
159 // Check for an improvement - if not, roll back and return no result
160 const double newScore = geometrize::core::differencePartial(m_target, before, m_current, m_lastScore, lines);
161 const auto& addShapeCondition = addShapePrecondition ? addShapePrecondition : defaultAddShapePrecondition;
162 if(!addShapeCondition(m_lastScore, newScore, *shape, lines, color, before, m_current, m_target)) {
163 m_current = before;
164 return {};
165 }
166
167 // Improvement - set new baseline and return the new shape
168 m_lastScore = newScore;
169 const geometrize::ShapeResult result{m_lastScore, color, shape};
170 return { result };
171 }
std::vector< geometrize::State > getHillClimbState(const std::function< std::shared_ptr< geometrize::Shape >(void)> shapeCreator, const std::uint8_t alpha, const std::uint32_t shapeCount, const std::uint32_t maxShapeMutations, std::uint32_t maxThreads, const geometrize::core::EnergyFunction energyFunction)
Definition: model.cpp:85
The State class relates a shape and related properties to a measure of how close it brings the workin...
Definition: state.h:21
geometrize::rgba computeColor(const geometrize::Bitmap &target, const geometrize::Bitmap &current, const std::vector< geometrize::Scanline > &lines, const std::uint8_t alpha)
computeColor Calculates the color of the scanlines.
Definition: core.cpp:122
The rgba struct is a helper for manipulating RGBA8888 color data.
Definition: rgba.h:13
Here is the call graph for this function:

Member Data Documentation

◆ defaultMaxThreads

const std::uint32_t geometrize::Model::ModelImpl::defaultMaxThreads {4}
staticprivate

◆ m_baseRandomSeed

std::atomic<std::uint32_t> geometrize::Model::ModelImpl::m_baseRandomSeed
private

The base value used for seeding the random number generator (the one the user has control over).

◆ m_current

geometrize::Bitmap geometrize::Model::ModelImpl::m_current
private

The current bitmap.

◆ m_lastScore

double geometrize::Model::ModelImpl::m_lastScore
private

Score derived from calculating the difference between bitmaps.

◆ m_randomSeedOffset

std::atomic<std::uint32_t> geometrize::Model::ModelImpl::m_randomSeedOffset
private

Seed used for random number generation. Note: incremented by each std::async call used for model stepping.

◆ m_target

geometrize::Bitmap geometrize::Model::ModelImpl::m_target
private

The target bitmap, the bitmap we aim to approximate.


The documentation for this class was generated from the following file: