2
#include "../../SyntopiaCore/Logging/Logging.h"
3
#include "../../SyntopiaCore/Exceptions/Exception.h"
4
#include "../../SyntopiaCore/Misc/ColorUtils.h"
5
#include "../../SyntopiaCore/Math/Vector3.h"
7
#include <QProgressDialog>
8
#include <QApplication>
10
using namespace SyntopiaCore::Logging;
11
using namespace SyntopiaCore::Math;
12
using namespace SyntopiaCore::Exceptions;
14
namespace StructureSynth {
17
Builder::Builder(Rendering::Renderer* renderTarget, RuleSet* ruleSet) : renderTarget(renderTarget), ruleSet(ruleSet) {
18
maxGenerations = 1000;
22
hasSeedChanged = false;
26
void Builder::build() {
28
INFO("Starting builder...");
30
/// Push first generation state
31
stack.append(RuleState(ruleSet->getStartRule(), State()));
32
int generationCounter = 0;
34
QProgressDialog progressDialog("Building objects...", "Cancel", 0, 100, 0);
35
progressDialog.setWindowModality(Qt::WindowModal);
36
progressDialog.setMinimumDuration(0);
37
progressDialog.show();
38
progressDialog.setValue(0);
42
while (generationCounter < maxGenerations && objects < maxObjects) {
46
p = objects/(double)maxObjects;
50
if (maxGenerations>0) {
51
p2 = generationCounter/(double)maxGenerations;
55
if (p2 > p) progress = p2;
57
if (maxObjects<=0 && maxGenerations<=0) {
58
progress = (generationCounter%9)/9.0;
61
if (lastValue != (int)(progress*100.0)) {
62
progressDialog.setValue((int)(progress*100.0));
63
progressDialog.setLabelText(
64
QString("Building objects...\r\n\r\nGeneration: %1\r\nObjects: %2\r\nPending rules: %3")
65
.arg(generationCounter).arg(objects).arg(stack.size()));
66
qApp->processEvents();
69
lastValue = (int)(progress*100.0);
71
if (progressDialog.wasCanceled()) {
77
// Now iterate though all RuleState's on stack and create next generation.
78
//INFO(QString("Executing generation %1 with %2 individuals").arg(generationCounter).arg(stack.size()));
80
for (int i = 0; i < stack.size(); i++) {
81
// INFO("Executing: " + stack[i].rule->getName());
82
state = stack[i].state;
83
stack[i].rule->apply(this);
87
if (stack.size() == 0) break; // no need to continue...
90
progressDialog.setValue(100);
91
progressDialog.hide();
93
if (progressDialog.wasCanceled()) {
94
INFO("User terminated.");
97
if (objects == maxObjects) {
98
INFO(QString("Terminated because maximum number of objects reached (%1).").arg(maxObjects));
99
INFO(QString("Use 'Set MaxObjects' command to increase this number."));
102
if (generationCounter == maxGenerations) {
103
INFO(QString("Terminated because maximum number of generations reached (%1).").arg(maxGenerations));
104
INFO(QString("Use 'Set Maxdepth' command to increase this number."));
106
INFO("Done building...");
109
void Builder::setCommand(QString command, QString param) {
110
if (command == "maxdepth") {
111
//INFO(QString("Setting 'maxgenerations' to %1").arg(param));
113
int i = param.toInt(&succes);
114
if (!succes) throw Exception(QString("Command 'maxdepth' expected integer parameter. Found: %1").arg(param));
116
} else if (command == "maxobjects") {
117
//INFO(QString("Setting 'maxgenerations' to %1").arg(param));
119
int i = param.toInt(&succes);
120
if (!succes) throw Exception(QString("Command 'maxobjects' expected integer parameter. Found: %1").arg(param));
122
} else if (command == "seed") {
124
int i = param.toInt(&succes);
125
if (!succes) throw Exception(QString("Command 'seed' expected integer parameter. Found: %1").arg(param));
127
hasSeedChanged = true;
129
} else if (command == "background") {
131
if (!c.isValid()) throw Exception(QString("Command 'background' expected a valid color identifier: Found: %1").arg(param));
132
renderTarget->setBackgroundColor(Vector3f(c.red() / 255.0, c.green() / 255.0, c.blue() / 255.0) );
133
} else if (command == "scale") {
135
double s = param.toDouble(&succes);
136
if (!succes) throw Exception(QString("Command 'scale' expected floating point parameter. Found: %1").arg(param));
137
renderTarget->setScale(s);
138
} else if (command == "translation") {
140
Vector3f v3(param, succes);
141
if (!succes) throw Exception(QString("Command 'translation' expected vector (such as [1 3 -10.1]). Found: %1").arg(param));
142
renderTarget->setTranslation(v3);
143
} else if (command == "pivot") {
145
Vector3f v3(param, succes);
146
if (!succes) throw Exception(QString("Command 'pivot' expected vector (such as [1 3 -10.1]). Found: %1").arg(param));
147
renderTarget->setPivot(v3);
148
} else if (command == "rotation") {
150
Matrix4f m4(param, succes);
151
if (!succes) throw Exception(QString("Command 'rotation' expected matrix (such as [1 0 0 0 1 0 0 0 1]). Found: %1").arg(param));
152
renderTarget->setRotation(m4);
153
} else if (command == "opengl") {
154
INFO("Render commands for 'opengl' not impl'ed yet!");
155
} else if (command == "template") {
156
renderTarget->callCommand(command,param);
158
throw Exception(QString("Unknown command: %1").arg(command));
162
ExecutionStack& Builder::getNextStack() {